Discussion:
[PATCH 2/2] Putting TPS6235x into the power regulator framework
(too old to reply)
y***@india.ti.com
2008-12-04 10:25:06 UTC
Permalink
From: Manikandan Pillai <***@ti.com>

Resending this patch with comments fixed :
This patch moves the TPS6235x drivers from the drivers/i2c to drivers/
regulator to put the TPS6235x drivers under the power regulator framework

suffix core_pwr and mpu_pwr has been removed
I2C bus speeds replaced with numbers again
Camel case has been removed
TPS moved into regulator framework and drivers/i2c/chips left untouched.

Not fixed comments:
Not clear on how to implement runtime check for PR785 and would require some
inputs on implementing the same.

Signed-off-by: Manikandan Pillai <***@ti.com>
---
arch/arm/mach-omap2/board-omap3evm.c | 6 +-
arch/arm/plat-omap/devices.c | 78 +++++
arch/arm/plat-omap/i2c.c | 21 +-
drivers/i2c/busses/i2c-omap.c | 154 +++++++++-
drivers/i2c/chips/Kconfig | 23 ++
drivers/regulator/Kconfig | 7 +
drivers/regulator/Makefile | 1 +
drivers/regulator/core.c | 27 --
drivers/regulator/tps6235x-regulator.c | 544 ++++++++++++++++++++++++++++++++
include/linux/regulator/driver.h | 23 ++-
10 files changed, 848 insertions(+), 36 deletions(-)
create mode 100644 drivers/regulator/tps6235x-regulator.c

diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 22ac2e9..ab3070d 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -168,7 +168,7 @@ static struct i2c_board_info __initdata tps_6235x_i2c_board_info[] = {

static int __init omap3_evm_i2c_init(void)
{
-#if defined(CONFIG_PR785)
+#if defined(CONFIG_PR785) && defined(CONFIG_TPS6235X_I2C2)
omap_register_i2c_bus(1, 2600, tps_6235x_i2c_board_info,
ARRAY_SIZE(tps_6235x_i2c_board_info));
#endif
@@ -178,6 +178,10 @@ static int __init omap3_evm_i2c_init(void)
#endif
omap_register_i2c_bus(2, 400, NULL, 0);
omap_register_i2c_bus(3, 400, NULL, 0);
+#if defined(CONFIG_PR785) && defined(CONFIG_TPS6235X_I2C4)
+ omap_register_i2c_bus(4, 2600, tps_6235x_i2c_board_info,
+ ARRAY_SIZE(tps_6235x_i2c_board_info));
+#endif
return 0;
}

diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 25c6d10..4c81eaf 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -27,6 +27,7 @@
#include <mach/gpio.h>
#include <mach/dsp_common.h>
#include <mach/mcbsp.h>
+#include <linux/regulator/machine.h>

#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)

@@ -350,6 +351,83 @@ static void omap_init_rng(void)
static inline void omap_init_rng(void) {}
#endif

+/*-------------------------------------------------------------------------*/
+#if defined(CONFIG_PR785) || defined(CONFIG_PR785_MODULE)
+
+static struct regulator_init_data tps_regulator_data[];
+
+static struct resource tps6235x_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device omap_tps6235x_device[] = {
+ {
+ .name = "tps6235x_reg",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(tps6235x_resources),
+ .resource = tps6235x_resources,
+ .dev = {
+ .platform_data = &tps_regulator_data[0],
+ },
+ },
+ {
+ .name = "tps6235x_reg",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(tps6235x_resources),
+ .resource = tps6235x_resources,
+ .dev = {
+ .platform_data = &tps_regulator_data[1],
+ },
+ },
+};
+
+static struct regulator_consumer_supply tps6235x_consumers[] = {
+ {
+ .dev = &omap_tps6235x_device[0].dev,
+ .supply = "tps62352",
+ },
+ {
+ .dev = &omap_tps6235x_device[1].dev,
+ .supply = "tps62353",
+ },
+};
+
+static struct regulator_init_data tps_regulator_data[] = {
+ {
+ .constraints = {
+ .min_uV = 750000,
+ .max_uV = 1537000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &tps6235x_consumers[0],
+ },
+ {
+ .constraints = {
+ .min_uV = 750000,
+ .max_uV = 1537000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &tps6235x_consumers[1],
+ },
+
+};
+
+static void omap_init_pr785(void)
+{
+ (void) platform_device_register(&omap_tps6235x_device[0]);
+ (void) platform_device_register(&omap_tps6235x_device[1]);
+}
+#else
+static inline void omap_init_pr785(void) {}
+#endif
+/*-------------------------------------------------------------------------*/
+
/*
* This gets called after board-specific INIT_MACHINE, and initializes most
* on-chip peripherals accessible on this board (except for few like USB):
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index 89a6ab0..e0c763a 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -35,6 +35,7 @@
#define OMAP2_I2C_BASE3 0x48060000

static const char name[] = "i2c_omap";
+static const char name4[] = "i2c4_omap";

#define I2C_RESOURCE_BUILDER(base, irq) \
{ \
@@ -54,6 +55,7 @@ static struct resource i2c_resources[][2] = {
#endif
#if defined(CONFIG_ARCH_OMAP34XX)
{ I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, INT_34XX_I2C3_IRQ) },
+ { I2C_RESOURCE_BUILDER(0x0, 0x0) },
#endif
};

@@ -68,6 +70,17 @@ static struct resource i2c_resources[][2] = {
}, \
}

+#define I2C_DEV_BUILDER4(bus_id, res, data) \
+ { \
+ .id = (bus_id), \
+ .name = name4, \
+ .num_resources = ARRAY_SIZE(res), \
+ .resource = (res), \
+ .dev = { \
+ .platform_data = (data), \
+ }, \
+ }
+
static u32 i2c_rate[ARRAY_SIZE(i2c_resources)];
static struct platform_device omap_i2c_devices[] = {
I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_rate[0]),
@@ -76,6 +89,7 @@ static struct platform_device omap_i2c_devices[] = {
#endif
#if defined(CONFIG_ARCH_OMAP34XX)
I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_rate[2]),
+ I2C_DEV_BUILDER4(4, i2c_resources[3], &i2c_rate[3]),
#endif
};

@@ -132,7 +146,8 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
else if (cpu_is_omap24xx())
ports = 2;
else if (cpu_is_omap34xx())
- ports = 3;
+ /* There are 4 I2C controller on OMAP3 */
+ ports = 4;

BUG_ON(bus_id < 1 || bus_id > ports);

@@ -141,7 +156,6 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
if (err)
return err;
}
-
pdev = &omap_i2c_devices[bus_id - 1];
*(u32 *)pdev->dev.platform_data = clkrate;

@@ -159,6 +173,7 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
res[1].start = irq;
}

- omap_i2c_mux_pins(bus_id - 1);
+ if (bus_id != 4)
+ omap_i2c_mux_pins(bus_id - 1);
return platform_device_register(pdev);
}
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 96f3bed..bf8dd1e 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -157,6 +157,13 @@
#define SYSC_CLOCKACTIVITY_FCLK 0x2


+/* I2C4 Programming interface register address */
+#define OMAP_I2C4_PRM_VC_BYPASS_VAL (IO_ADDRESS(0x4830723C))
+#define OMAP_I2C4_PRM_SLAVE_ADDR_MSK (0x7F)
+#define OMAP_I2C4_PRM_REG_SHIFT (8)
+#define OMAP_I2C4_PRM_DATA_SHIFT (16)
+#define OMAP_I2C4_PRM_VALID_MSK (1<<24)
+
struct omap_i2c_dev {
struct device *dev;
void __iomem *base; /* virtual */
@@ -524,7 +531,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
return -EIO;
}

-
/*
* Prepare controller for a transaction and call omap_i2c_xfer_msg
* to do the work during IRQ processing.
@@ -561,6 +567,70 @@ omap_i2c_func(struct i2c_adapter *adap)
return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
}

+/*
+ * I2C4 is a special I2C controller unlike I2C1, I2C2 and I2C3.
+ * Prepare controller for a transaction and write into appropriate
+ * registers for transferring data. Only writes are supported on I2C4.
+ */
+static int omap_i2c4_xfer_msg(struct i2c_adapter *adap,
+ struct i2c_msg *msg, int stop)
+{
+ struct omap_i2c_dev *dev = i2c_get_adapdata(adap);
+ unsigned int r;
+ unsigned char *cptr;
+ unsigned char regval, dataval;
+
+ dev_dbg(dev->dev, "I2C4:addr: 0x%04x, len: %d,flags: 0x%x,stop: %d\n",
+ msg->addr, msg->len, msg->flags, stop);
+
+ if (msg->len == 0)
+ return -EINVAL;
+
+ dev->buf_len = msg->len;
+
+ cptr = msg->buf;
+ regval = *cptr;
+ cptr++;
+ dataval = *cptr;
+
+ r = (((msg->addr) & OMAP_I2C4_PRM_SLAVE_ADDR_MSK) |
+ (regval << OMAP_I2C4_PRM_REG_SHIFT) |
+ (dataval << OMAP_I2C4_PRM_DATA_SHIFT) |
+ OMAP_I2C4_PRM_VALID_MSK);
+
+ regval = *(volatile unsigned int *)OMAP_I2C4_PRM_VC_BYPASS_VAL;
+
+ while (regval & OMAP_I2C4_PRM_VALID_MSK)
+ regval = *(volatile unsigned int *)OMAP_I2C4_PRM_VC_BYPASS_VAL;
+
+ *(volatile unsigned int *)OMAP_I2C4_PRM_VC_BYPASS_VAL = r;
+ return 0;
+}
+
+/*
+ * I2C4 is a special I2C controller unlike I2C1, I2C2 and I2C3.
+ * Prepare controller for a transaction and call omap_i2c4_xfer_msg
+ * to do the work during IRQ processing.
+ * Only writes are supported on I2C4.
+ */
+static int
+omap_i2c4_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+{
+ int i;
+ int r;
+
+ for (i = 0; i < num; i++) {
+ r = omap_i2c4_xfer_msg(adap, &msgs[i], (i == (num - 1)));
+ if (r != 0)
+ break;
+ }
+
+ if (r == 0)
+ return num;
+ return r;
+}
+
+
static inline void
omap_i2c_complete_cmd(struct omap_i2c_dev *dev, u16 err)
{
@@ -761,6 +831,11 @@ omap_i2c_isr(int this_irq, void *dev_id)
return count ? IRQ_HANDLED : IRQ_NONE;
}

+static const struct i2c_algorithm omap_i2c4_algo = {
+ .master_xfer = omap_i2c4_xfer,
+ .functionality = omap_i2c_func,
+};
+
static const struct i2c_algorithm omap_i2c_algo = {
.master_xfer = omap_i2c_xfer,
.functionality = omap_i2c_func,
@@ -839,8 +914,8 @@ omap_i2c_probe(struct platform_device *pdev)
*/
dev->fifo_size = (dev->fifo_size / 2);
dev->b_hw = 1; /* Enable hardware fixes */
- }

+ }
/* reset ASAP, clearing any IRQs */
omap_i2c_init(dev);

@@ -856,13 +931,14 @@ omap_i2c_probe(struct platform_device *pdev)
pdev->id, dev->rev >> 4, dev->rev & 0xf, dev->speed);

omap_i2c_idle(dev);
-
adap = &dev->adapter;
i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON;
strncpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));
+ /* if BusId is 1-3 then algorithm is omap_i2c_algo */
adap->algo = &omap_i2c_algo;
+
adap->dev.parent = &pdev->dev;

/* i2c device drivers may be active on return from add_adapter() */
@@ -911,6 +987,61 @@ omap_i2c_remove(struct platform_device *pdev)
return 0;
}

+static int __init
+omap_i2c4_probe(struct platform_device *pdev)
+{
+ struct omap_i2c_dev *dev;
+ struct i2c_adapter *adap;
+ int r = 0;
+ u32 *speed = NULL;
+
+ dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL);
+ if (!dev)
+ r = -ENOMEM;
+
+ if (pdev->dev.platform_data != NULL)
+ speed = (u32 *) pdev->dev.platform_data;
+ else
+ *speed = 100; /* Defualt speed */
+
+ dev->speed = *speed;
+ dev->idle = 1;
+ dev->dev = &pdev->dev;
+
+ platform_set_drvdata(pdev, dev);
+
+ r = omap_i2c_get_clocks(dev);
+
+ adap = &dev->adapter;
+ i2c_set_adapdata(adap, dev);
+ adap->owner = THIS_MODULE;
+ adap->class = I2C_CLASS_HWMON;
+ strncpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));
+ /* BusId is 4(I2C4) then algorithm is different */
+ adap->algo = &omap_i2c4_algo;
+
+ adap->dev.parent = &pdev->dev;
+
+ /* i2c device drivers may be active on return from add_adapter() */
+ adap->nr = pdev->id;
+ r = i2c_add_numbered_adapter(adap);
+ if (r)
+ dev_err(dev->dev, "failure adding adapter\n");
+
+ return r;
+}
+
+static int
+omap_i2c4_remove(struct platform_device *pdev)
+{
+ struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
+ platform_set_drvdata(pdev, NULL);
+ i2c_del_adapter(&dev->adapter);
+ kfree(dev);
+ return 0;
+}
+
+
static struct platform_driver omap_i2c_driver = {
.probe = omap_i2c_probe,
.remove = omap_i2c_remove,
@@ -920,17 +1051,32 @@ static struct platform_driver omap_i2c_driver = {
},
};

+static struct platform_driver omap_i2c4_driver = {
+ .probe = omap_i2c4_probe,
+ .remove = omap_i2c4_remove,
+ .driver = {
+ .name = "i2c4_omap",
+ .owner = THIS_MODULE,
+ },
+};
+
+
/* I2C may be needed to bring up other drivers */
static int __init
omap_i2c_init_driver(void)
{
- return platform_driver_register(&omap_i2c_driver);
+ int ret = 0;
+ ret = platform_driver_register(&omap_i2c_driver);
+ ret = platform_driver_register(&omap_i2c4_driver);
+
+ return ret;
}
subsys_initcall(omap_i2c_init_driver);

static void __exit omap_i2c_exit_driver(void)
{
platform_driver_unregister(&omap_i2c_driver);
+ platform_driver_unregister(&omap_i2c4_driver);
}
module_exit(omap_i2c_exit_driver);

diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index d61589b..5702520 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -194,6 +194,29 @@ config SENSORS_MAX6875
This driver can also be built as a module. If so, the module
will be called max6875.

+choice
+ prompt "TPS6235X driver support"
+ depends on I2C=y && PR785=y
+ default n
+ help
+ nothing.
+
+ config TPS6235X_I2C2
+ bool "TPS6235X_I2C2"
+ help
+ Say yes here if you have TPS6235x devices connected to I2C Bus2
+ on PR785 Power module. Note that while selecting this option,
+ TPS6235X_I2C4 should not be selected.
+
+ config TPS6235X_I2C4
+ bool "TPS6235X_I2C4"
+ help
+ Say yes here if you have TPS6235x devices connected to I2C Bus4
+ on PR785 Power module. Note that while selecting this option,
+ TPS6235X_I2C2 should not be selected.
+
+endchoice
+
config SENSORS_TSL2550
tristate "Taos TSL2550 ambient light sensor"
depends on EXPERIMENTAL
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 0765389..6a827e5 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -80,4 +80,11 @@ config REGULATOR_DA903X
Say y here to support the BUCKs and LDOs regulators found on
Dialog Semiconductor DA9030/DA9034 PMIC.

+config REGULATOR_TPS6235X
+ bool "TPS6235X Power regulator for OMAP3EVM"
+ depends on PR785
+ help
+ This driver supports the voltage regulators provided by TPS6235x chips.
+ The TPS62352 and TPS62353 are mounted on PR785 Power module card for
+ providing voltage regulator functions.
endif
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 0dacb18..fdc5f5b 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -12,5 +12,6 @@ obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
+obj-$(CONFIG_REGULATOR_TPS6235X)+= tps6235x-regulator.o

ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 02a7744..901f402 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -30,33 +30,6 @@ static LIST_HEAD(regulator_list);
static LIST_HEAD(regulator_map_list);

/**
- * struct regulator_dev
- *
- * Voltage / Current regulator class device. One for each regulator.
- */
-struct regulator_dev {
- struct regulator_desc *desc;
- int use_count;
-
- /* lists we belong to */
- struct list_head list; /* list of all regulators */
- struct list_head slist; /* list of supplied regulators */
-
- /* lists we own */
- struct list_head consumer_list; /* consumers we supply */
- struct list_head supply_list; /* regulators we supply */
-
- struct blocking_notifier_head notifier;
- struct mutex mutex; /* consumer lock */
- struct module *owner;
- struct device dev;
- struct regulation_constraints *constraints;
- struct regulator_dev *supply; /* for tree */
-
- void *reg_data; /* regulator_dev data */
-};
-
-/**
* struct regulator_map
*
* Used to provide symbolic supply names to devices.
diff --git a/drivers/regulator/tps6235x-regulator.c b/drivers/regulator/tps6235x-regulator.c
new file mode 100644
index 0000000..8a900db
--- /dev/null
+++ b/drivers/regulator/tps6235x-regulator.c
@@ -0,0 +1,544 @@
+/*
+ * tps6235x-regulator.c -- support regulators in tps6235x family chips
+ *
+ * Copyright (C) 2008 David Brownell
+ * Author : Manikandan Pillai<***@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/regulator/consumer.h>
+
+/* Minimum and Maximum dc-dc voltage supported by the TPS6235x devices
+All voltages given in millivolts */
+#define PR785_MIN_CORE_VOLT 750
+#define PR785_MAX_CORE_VOLT 1537
+#define PR785_MIN_MPU_VOLT 750
+#define PR785_MAX_MPU_VOLT 1537
+
+/* Maximum number of bytes to be read in a single read */
+#define PR785_RETRY_COUNT 0x3
+
+/* Register bit settings */
+#define TPS6235X_EN_DCDC (0x1 << 0x7)
+#define TPS6235X_VSM_MSK (0x3F)
+#define TPS6235X_EN_SYN_MSK (0x1 << 0x5)
+#define TPS6235X_SW_VOLT_MSK (0x1 << 0x4)
+#define TPS6235X_PWR_OK_MSK (0x1 << 0x5)
+#define TPS6235X_OUT_DIS_MSK (0x1 << 0x6)
+#define TPS6235X_GO_MSK (0x1 << 0x7)
+
+/*
+ * These chips are often used in OMAP-based systems.
+ *
+ * This driver implements software-based resource control for various
+ * voltage regulators. This is usually augmented with state machine
+ * based control.
+ */
+struct tps_6235x_info {
+ unsigned int state;
+ unsigned int tps_i2c_addr;
+ struct i2c_client *client;
+ struct device *i2c_dev;
+ /* platform data holder */
+ void *pdata;
+};
+
+static struct tps_6235x_info tps_6235x_infodata[2];
+
+
+#ifndef REGULATOR_MODE_OFF
+#define REGULATOR_MODE_OFF 0
+#endif
+
+
+/* LDO control registers ... offset is from the base of its register bank.
+ * The first three registers of all power resource banks help hardware to
+ * manage the various resource groups.
+ */
+
+#define TPS6235X_REG_VSEL0 0
+#define TPS6235X_REG_VSEL1 1
+#define TPS6235X_REG_CTRL1 2
+#define TPS6235X_REG_CTRL2 3
+#define TPS6235X_REG_MAX TPS6235X_REG_CTRL2
+
+#define MODULE_NAME "tps6235x_power"
+
+/* Debug functions */
+#ifdef DEBUG
+
+#define dump_reg(client, reg, val) \
+ do { \
+ tps6235x_read_reg(client, reg, &val); \
+ dev_dbg(&(client)->dev, "Reg(0x%.2X): 0x%.2X\n", reg, val); \
+ } while (0)
+
+#endif /* #ifdef DEBUG */
+
+/* Device addresses for PR785 card */
+#define PR785_62352_CORE_ADDR 0x4A
+#define PR785_62353_MPU_ADDR 0x48
+
+/* Minimum and Maximum dc-dc voltage supported by the TPS6235x devices
+All voltages given in millivolts */
+#define PR785_MIN_CORE_VOLT 750
+#define PR785_MAX_CORE_VOLT 1537
+#define PR785_MIN_MPU_VOLT 750
+#define PR785_MAX_MPU_VOLT 1537
+
+/* Maximum number of bytes to be read in a single read */
+#define PR785_RETRY_COUNT 0x3
+
+/* Register bit settings */
+#define TPS6235X_EN_DCDC (0x1 << 0x7)
+#define TPS6235X_VSM_MSK (0x3F)
+#define TPS6235X_EN_SYN_MSK (0x1 << 0x5)
+#define TPS6235X_SW_VOLT_MSK (0x1 << 0x4)
+#define TPS6235X_PWR_OK_MSK (0x1 << 0x5)
+#define TPS6235X_OUT_DIS_MSK (0x1 << 0x6)
+#define TPS6235X_GO_MSK (0x1 << 0x7)
+
+int pr785_enbl_dcdc(unsigned char tps_mod_type, unsigned int en_flag);
+int pr785_get_dcdc_volt(unsigned char tps_mod_type, unsigned int *millivolts);
+int pr785_set_dcdc_volt(unsigned char tps_mod_type, unsigned int millivolts);
+
+static int tps6235x_dcdc_is_enabled(struct regulator_dev *dev)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+ return tps_info->state;
+}
+
+static int tps6235x_dcdc_enable(struct regulator_dev *dev)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+
+ tps_info->state = 1;
+ return pr785_enbl_dcdc(tps_info->tps_i2c_addr, 1);
+}
+
+static int tps6235x_dcdc_disable(struct regulator_dev *dev)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+
+ tps_info->state = 0;
+ return pr785_enbl_dcdc(tps_info->tps_i2c_addr, 0);
+}
+
+static int tps6235x_dcdc_get_voltage(struct regulator_dev *dev)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+ unsigned int millivolts;
+
+ pr785_get_dcdc_volt(tps_info->tps_i2c_addr, &millivolts);
+ return millivolts * 1000;
+}
+
+static int tps6235x_dcdc_set_voltage(struct regulator_dev *dev,
+ int min_uV, int max_uV)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+ unsigned int millivolts = max_uV / 1000;
+
+ return pr785_set_dcdc_volt(tps_info->tps_i2c_addr, millivolts) ;
+}
+
+
+static struct regulator_ops tps62352_dcdc_ops = {
+ .is_enabled = tps6235x_dcdc_is_enabled,
+ .get_voltage = tps6235x_dcdc_get_voltage,
+ .set_voltage = tps6235x_dcdc_set_voltage,
+};
+
+static struct regulator_ops tps62353_dcdc_ops = {
+ .is_enabled = tps6235x_dcdc_is_enabled,
+ .enable = tps6235x_dcdc_enable,
+ .disable = tps6235x_dcdc_disable,
+ .get_voltage = tps6235x_dcdc_get_voltage,
+ .set_voltage = tps6235x_dcdc_set_voltage,
+};
+
+
+static struct regulator_desc regulators[] = {
+ {
+ .name = "tps62352",
+ .id = 2,
+ .ops = &tps62352_dcdc_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "tps62353",
+ .id = 3,
+ .ops = &tps62353_dcdc_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int tps6235xreg_probe(struct platform_device *pdev)
+{
+ struct tps_6235x_info *info;
+ struct regulator_dev *rdev = NULL;
+
+ info = &tps_6235x_infodata[(pdev->id-2)];
+
+ rdev = regulator_register(&regulators[(pdev->id-2)], &pdev->dev, info);
+ if (rdev == NULL)
+ printk(KERN_ERR "err in regulator registry = %d\n", pdev->id);
+
+ platform_set_drvdata(pdev, rdev);
+
+ return 0;
+}
+
+static int __devexit tps6235xreg_remove(struct platform_device *pdev)
+{
+ regulator_unregister(platform_get_drvdata(pdev));
+ return 0;
+}
+
+MODULE_ALIAS("platform:tps6235x_reg");
+
+static struct platform_driver tps6235xreg_driver = {
+ .probe = tps6235xreg_probe,
+ .remove = __devexit_p(tps6235xreg_remove),
+ .driver.name = "tps6235x_reg",
+ .driver.owner = THIS_MODULE,
+};
+
+static int __init tps6235xreg_init(void)
+{
+ return platform_driver_register(&tps6235xreg_driver);
+}
+late_initcall(tps6235xreg_init);
+
+static void __exit tps6235xreg_exit(void)
+{
+ platform_driver_unregister(&tps6235xreg_driver);
+}
+module_exit(tps6235xreg_exit)
+
+MODULE_DESCRIPTION("TPS6235X regulator driver");
+MODULE_LICENSE("GPL");
+
+
+/*
+ * Get client pointer for a particular device
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static struct i2c_client *tps_6235x_get_client(unsigned char tps_i2c_addr)
+{
+ if (tps_i2c_addr == PR785_62352_CORE_ADDR)
+ return tps_6235x_infodata[0].client;
+ else if (tps_i2c_addr == PR785_62353_MPU_ADDR)
+ return tps_6235x_infodata[1].client;
+ else
+ return NULL;
+}
+
+/*
+ * Read a value from a register in an tps_6235x device.
+ * The value is returned in 'val'.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int tps_6235x_read_reg(struct i2c_client *client, u8 reg, u8 *val)
+{
+ u8 data;
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ data = i2c_smbus_read_byte_data(client, reg);
+ *val = data;
+ return 0;
+}
+
+/*
+ * Write a value to a register in an tps_6235x device.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int tps_6235x_write_reg(struct i2c_client *client, u8 reg, u8 val)
+{
+ int err;
+ int retry = 0;
+
+ if (!client->adapter)
+ return -ENODEV;
+
+again:
+ err = i2c_smbus_write_byte_data(client, reg, val);
+ if (err >= 0)
+ return 0;
+
+ dev_err(&client->dev,
+ "wrote 0x%.2x to offset 0x%.2x error %d\n", val, reg, err);
+
+ if (retry <= PR785_RETRY_COUNT) {
+ dev_info(&client->dev, "retry ... %d\n", retry);
+ retry++;
+ schedule_timeout(msecs_to_jiffies(20));
+ goto again;
+ }
+ return err;
+}
+
+
+/**
+* pwr_i2c_read - Allows the caller to read one register from TPS device
+* based on the address given. For the PR785 it reads
+* only 1 byte into a specified register
+* tps_mod_type - Enum for the device to be read
+* reg - Register to be read from(value has to be between 0-3
+* val - value read from the reg
+* Retval - 0 -> Success else non-zero
+**/
+int pwr_i2c_read(unsigned char tps_mod_type, u8 reg, u8 *val)
+{
+ struct i2c_client *client;
+
+ client = tps_6235x_get_client(tps_mod_type);
+ /* check if register is less than <= 3 Register is 0 -3 */
+ if (reg > TPS6235X_REG_MAX)
+ return -1;
+
+ return tps_6235x_read_reg(client, reg, val);
+}
+EXPORT_SYMBOL(pwr_i2c_read);
+
+/**
+* pwr_i2c_write - Allows the caller to write one register from TPS device
+* based on the address given. For the PR785 it writes
+* only 1 byte into a specified register
+* tps_mod_type - Enum for the device to be written
+* reg - Register to be written to(value has to be between 0-3
+* val - value to be written to reg
+* Retval - 0 -> Success else non-zero
+**/
+int pwr_i2c_write(unsigned char tps_mod_type, u8 reg, u8 val)
+{
+ struct i2c_client *client;
+
+ client = tps_6235x_get_client(tps_mod_type);
+
+ /* check if register is less than <= 3 Register is 0 -3 */
+ if (reg > TPS6235X_REG_MAX)
+ return -1;
+
+ return tps_6235x_write_reg(client, reg, val);
+}
+EXPORT_SYMBOL(pwr_i2c_write);
+
+
+/**
+* TPSPR785 - Specific functions
+* pr785_enbl_dcdc - Allows the caller to enable or disable the TPS6235x device
+* on the PR785 board. The voltage for PR785 is selected by
+* VSEL1 register since VSEL pin is kept high
+*
+* flag - 1 == enable 0 == disable
+* Retval - 0 -> Success else non-zero
+**/
+int pr785_enbl_dcdc(unsigned char tps_mod_type, unsigned int en_flag)
+{
+ unsigned char vsel1;
+ int ret;
+
+ ret = pwr_i2c_read(tps_mod_type, TPS6235X_REG_VSEL1, &vsel1);
+ if (ret == 0) {
+ if (en_flag)
+ vsel1 |= TPS6235X_EN_DCDC;
+ else
+ vsel1 &= ~(TPS6235X_EN_DCDC);
+ ret = pwr_i2c_write(tps_mod_type, TPS6235X_REG_VSEL1, vsel1);
+ }
+ return ret;
+}
+EXPORT_SYMBOL(pr785_enbl_dcdc);
+
+/**
+* TPSPR785 - Specific functions
+* pr785_set_dcdc_volt - Allows the caller to set a particular voltage on
+* for CORE or MPU
+*
+* voltage - voltage to be set in millivolts (75--1537)
+* Retval - 0 -> Success else non-zero
+**/
+int pr785_set_dcdc_volt(unsigned char tps_mod_type, unsigned int millivolts)
+{
+ unsigned char vsel1;
+ unsigned int volt;
+
+ /* check if the millivolts is within range */
+ if ((millivolts < PR785_MIN_CORE_VOLT) ||
+ (millivolts > PR785_MAX_CORE_VOLT))
+ return -1;
+
+ /* Output voltage set is = min_op_volt + ( VSM * 12.5mv) */
+ volt = millivolts - PR785_MIN_CORE_VOLT;
+ volt /= 25;
+ volt *= 2;
+ vsel1 = ((TPS6235X_EN_DCDC) | (volt & TPS6235X_VSM_MSK));
+ return pwr_i2c_write(tps_mod_type, TPS6235X_REG_VSEL1, vsel1);
+}
+EXPORT_SYMBOL(pr785_set_dcdc_volt);
+
+/**
+* TPSPR785 - Specific functions
+* pr785_get_dcdc_volt - Allows the caller to get the set voltage on a
+* particular TPS 6235x device on PR785 card
+*
+* voltage - voltage to be set in millivolts (75--1537)
+* Retval - 0 -> Success else non-zero
+**/
+int pr785_get_dcdc_volt(unsigned char tps_mod_type, unsigned int *millivolts)
+{
+ unsigned char vsel1;
+ unsigned int volt;
+
+ /* Read the VSEL1 register to get VSM */
+ pwr_i2c_read(tps_mod_type, TPS6235X_REG_VSEL1, &vsel1);
+ /* Output voltage set is = min_op_volt + ( VSM * 12.5mv) */
+ /* To cut out floating point operation we will multiply by 25
+ divide by 2 */
+ volt = (((vsel1 & TPS6235X_VSM_MSK) * 25) / 2) + PR785_MIN_CORE_VOLT;
+ *millivolts = volt;
+ return 0;
+}
+EXPORT_SYMBOL(pr785_get_dcdc_volt);
+
+/**
+ * tps_6235x_probe - TPS6235x driver i2c probe handler
+ * @client: i2c driver client device structure
+ *
+ * Register PR785 as an i2c client device driver
+ */
+static struct i2c_driver tps_6235x_i2c_driver;
+
+static
+int tps_6235x_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ unsigned char reg_val;
+
+ printk(KERN_INFO "tps_6235x_probe:i2c_addr = %x\n", (int)client->addr);
+
+ /* Device probed is TPS62352 CORE pwr chip if driver_data = 0
+ Device probed is TPS62353 MPU pwr chip if driver_data = 1 */
+ tps_6235x_infodata[id->driver_data].client = client;
+ tps_6235x_infodata[id->driver_data].tps_i2c_addr = client->addr;
+ tps_6235x_infodata[id->driver_data].state = 1;
+ tps_6235x_infodata[id->driver_data].i2c_dev = &client->dev;
+
+ tps_6235x_read_reg(client, TPS6235X_REG_CTRL2, &reg_val);
+ reg_val |= (TPS6235X_OUT_DIS_MSK | TPS6235X_GO_MSK);
+ tps_6235x_write_reg(client, TPS6235X_REG_CTRL2, reg_val);
+ tps_6235x_read_reg(client, TPS6235X_REG_CTRL2, &reg_val);
+
+ i2c_set_clientdata(client, &tps_6235x_infodata[id->driver_data]);
+
+ if (reg_val & TPS6235X_PWR_OK_MSK)
+ printk(KERN_INFO "Power is OK %x\n", reg_val);
+ else
+ printk(KERN_INFO "Power not within range = %x\n", reg_val);
+ return 0;
+}
+
+/**
+ * tps_6235x_remove - TPS6235x driver i2c remove handler
+ * @client: i2c driver client device structure
+ *
+ * UnregisterPR785 as an i2c client device driver
+ */
+static int __exit tps_6235x_remove(struct i2c_client *client)
+{
+#ifdef DEBUG
+ printk(KERN_INFO "tps_6235x_remove invoked\n");
+#endif
+
+ if (!client->adapter)
+ return -ENODEV; /* our client isn't attached */
+
+ i2c_set_clientdata(client, NULL);
+
+ return 0;
+}
+
+
+static const struct i2c_device_id tps_6235x_id[] = {
+ { "tps62352", 0},
+ { "tps62353", 1},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, tps_6235x_id);
+
+static struct i2c_driver tps_6235x_i2c_driver = {
+ .driver = {
+ .name = MODULE_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = tps_6235x_probe,
+ .remove = __exit_p(tps_6235x_remove),
+ .id_table = tps_6235x_id,
+};
+
+/**
+ * tps_6235x_init
+ *
+ * Module init function
+ */
+static int __init tps_6235x_init(void)
+{
+ int err;
+
+#ifdef DEBUG
+ printk(KERN_INFO "tps_6235x_init invoked\n");
+#endif
+
+ err = i2c_add_driver(&tps_6235x_i2c_driver);
+ if (err) {
+ printk(KERN_ERR "Failed to register " MODULE_NAME ".\n");
+ return err;
+ } else
+ printk(KERN_INFO "I2c driver registered\n");
+
+ return 0;
+}
+
+/**
+ * tps_6235x_cleanup
+ *
+ * Module exit function
+ */
+static void __exit tps_6235x_cleanup(void)
+{
+#ifdef DEBUG
+ printk(KERN_INFO "tps_6235x_cleanup invoked\n");
+#endif
+ i2c_del_driver(&tps_6235x_i2c_driver);
+}
+
+late_initcall(tps_6235x_init);
+module_exit(tps_6235x_cleanup);
+
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("TPS6235x based PR785 linux driver");
+MODULE_LICENSE("GPL");
+
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index e37d805..9107344 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -18,9 +18,30 @@
#include <linux/device.h>
#include <linux/regulator/consumer.h>

-struct regulator_dev;
struct regulator_init_data;

+struct regulator_dev {
+ struct regulator_desc *desc;
+ int use_count;
+
+ /* lists we belong to */
+ struct list_head list; /* list of all regulators */
+ struct list_head slist; /* list of supplied regulators */
+
+ /* lists we own */
+ struct list_head consumer_list; /* consumers we supply */
+ struct list_head supply_list; /* regulators we supply */
+
+ struct blocking_notifier_head notifier;
+ struct mutex mutex; /* consumer lock */
+ struct module *owner;
+ struct device dev;
+ struct regulation_constraints *constraints;
+ struct regulator_dev *supply; /* for tree */
+
+ void *reg_data; /* regulator_dev data */
+};
+
/**
* struct regulator_ops - regulator operations.
*
--
1.5.6

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Felipe Balbi
2008-12-04 11:19:09 UTC
Permalink
Post by y***@india.ti.com
This patch moves the TPS6235x drivers from the drivers/i2c to drivers/
regulator to put the TPS6235x drivers under the power regulator framework
suffix core_pwr and mpu_pwr has been removed
I2C bus speeds replaced with numbers again
Camel case has been removed
TPS moved into regulator framework and drivers/i2c/chips left untouched.
Not clear on how to implement runtime check for PR785 and would require some
inputs on implementing the same.
This patch should be broken into smaller pieces.

The tps driver should come separated, drivers/regulator/core.c should go
to the maintainer in a separate patch, i2c-omap.c adding the i2c4
support, should be in a separate patch and Ccing Ben Dooks and Jean
Delvare.

More comments below.
Post by y***@india.ti.com
---
arch/arm/mach-omap2/board-omap3evm.c | 6 +-
arch/arm/plat-omap/devices.c | 78 +++++
arch/arm/plat-omap/i2c.c | 21 +-
drivers/i2c/busses/i2c-omap.c | 154 +++++++++-
drivers/i2c/chips/Kconfig | 23 ++
drivers/regulator/Kconfig | 7 +
drivers/regulator/Makefile | 1 +
drivers/regulator/core.c | 27 --
drivers/regulator/tps6235x-regulator.c | 544 ++++++++++++++++++++++++++++++++
include/linux/regulator/driver.h | 23 ++-
10 files changed, 848 insertions(+), 36 deletions(-)
create mode 100644 drivers/regulator/tps6235x-regulator.c
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 22ac2e9..ab3070d 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -168,7 +168,7 @@ static struct i2c_board_info __initdata tps_6235x_i2c_board_info[] = {
static int __init omap3_evm_i2c_init(void)
{
-#if defined(CONFIG_PR785)
+#if defined(CONFIG_PR785) && defined(CONFIG_TPS6235X_I2C2)
omap_register_i2c_bus(1, 2600, tps_6235x_i2c_board_info,
ARRAY_SIZE(tps_6235x_i2c_board_info));
#endif
@@ -178,6 +178,10 @@ static int __init omap3_evm_i2c_init(void)
#endif
omap_register_i2c_bus(2, 400, NULL, 0);
omap_register_i2c_bus(3, 400, NULL, 0);
+#if defined(CONFIG_PR785) && defined(CONFIG_TPS6235X_I2C4)
+ omap_register_i2c_bus(4, 2600, tps_6235x_i2c_board_info,
+ ARRAY_SIZE(tps_6235x_i2c_board_info));
+#endif
heh, i thought bus4 wasn't sw controllable :-s
Post by y***@india.ti.com
return 0;
}
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 25c6d10..4c81eaf 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -27,6 +27,7 @@
#include <mach/gpio.h>
#include <mach/dsp_common.h>
#include <mach/mcbsp.h>
+#include <linux/regulator/machine.h>
#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
@@ -350,6 +351,83 @@ static void omap_init_rng(void)
static inline void omap_init_rng(void) {}
#endif
+/*-------------------------------------------------------------------------*/
+#if defined(CONFIG_PR785) || defined(CONFIG_PR785_MODULE)
+
+static struct regulator_init_data tps_regulator_data[];
+
+static struct resource tps6235x_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ },
+};
this is not the correct place for it as only one board has this driver.
Move it to the proper board-file.
Post by y***@india.ti.com
+
+static struct platform_device omap_tps6235x_device[] = {
+ {
+ .name = "tps6235x_reg",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(tps6235x_resources),
+ .resource = tps6235x_resources,
+ .dev = {
+ .platform_data = &tps_regulator_data[0],
+ },
+ },
+ {
+ .name = "tps6235x_reg",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(tps6235x_resources),
+ .resource = tps6235x_resources,
+ .dev = {
+ .platform_data = &tps_regulator_data[1],
+ },
+ },
+};
+
+static struct regulator_consumer_supply tps6235x_consumers[] = {
+ {
+ .dev = &omap_tps6235x_device[0].dev,
+ .supply = "tps62352",
+ },
+ {
+ .dev = &omap_tps6235x_device[1].dev,
+ .supply = "tps62353",
supply should be Vdd, or Vbus or something more useful, not the chip's
name.
Post by y***@india.ti.com
+ },
+};
+
+static struct regulator_init_data tps_regulator_data[] = {
+ {
+ .constraints = {
+ .min_uV = 750000,
+ .max_uV = 1537000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &tps6235x_consumers[0],
+ },
+ {
+ .constraints = {
+ .min_uV = 750000,
+ .max_uV = 1537000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &tps6235x_consumers[1],
+ },
+
+};
+
+static void omap_init_pr785(void)
+{
+ (void) platform_device_register(&omap_tps6235x_device[0]);
+ (void) platform_device_register(&omap_tps6235x_device[1]);
+}
+#else
+static inline void omap_init_pr785(void) {}
+#endif
+/*-------------------------------------------------------------------------*/
+
/*
* This gets called after board-specific INIT_MACHINE, and initializes most
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index 89a6ab0..e0c763a 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -35,6 +35,7 @@
#define OMAP2_I2C_BASE3 0x48060000
static const char name[] = "i2c_omap";
+static const char name4[] = "i2c4_omap";
#define I2C_RESOURCE_BUILDER(base, irq) \
{ \
@@ -54,6 +55,7 @@ static struct resource i2c_resources[][2] = {
#endif
#if defined(CONFIG_ARCH_OMAP34XX)
{ I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, INT_34XX_I2C3_IRQ) },
+ { I2C_RESOURCE_BUILDER(0x0, 0x0) },
#endif
};
@@ -68,6 +70,17 @@ static struct resource i2c_resources[][2] = {
}, \
}
+#define I2C_DEV_BUILDER4(bus_id, res, data) \
+ { \
+ .id = (bus_id), \
+ .name = name4, \
+ .num_resources = ARRAY_SIZE(res), \
+ .resource = (res), \
+ .dev = { \
+ .platform_data = (data), \
+ }, \
+ }
+
static u32 i2c_rate[ARRAY_SIZE(i2c_resources)];
static struct platform_device omap_i2c_devices[] = {
I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_rate[0]),
@@ -76,6 +89,7 @@ static struct platform_device omap_i2c_devices[] = {
#endif
#if defined(CONFIG_ARCH_OMAP34XX)
I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_rate[2]),
+ I2C_DEV_BUILDER4(4, i2c_resources[3], &i2c_rate[3]),
#endif
};
@@ -132,7 +146,8 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
else if (cpu_is_omap24xx())
ports = 2;
else if (cpu_is_omap34xx())
- ports = 3;
+ /* There are 4 I2C controller on OMAP3 */
+ ports = 4;
BUG_ON(bus_id < 1 || bus_id > ports);
@@ -141,7 +156,6 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
if (err)
return err;
}
-
pdev = &omap_i2c_devices[bus_id - 1];
*(u32 *)pdev->dev.platform_data = clkrate;
@@ -159,6 +173,7 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
res[1].start = irq;
}
- omap_i2c_mux_pins(bus_id - 1);
+ if (bus_id != 4)
+ omap_i2c_mux_pins(bus_id - 1);
return platform_device_register(pdev);
}
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 96f3bed..bf8dd1e 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -157,6 +157,13 @@
#define SYSC_CLOCKACTIVITY_FCLK 0x2
+/* I2C4 Programming interface register address */
+#define OMAP_I2C4_PRM_VC_BYPASS_VAL (IO_ADDRESS(0x4830723C))
+#define OMAP_I2C4_PRM_SLAVE_ADDR_MSK (0x7F)
+#define OMAP_I2C4_PRM_REG_SHIFT (8)
+#define OMAP_I2C4_PRM_DATA_SHIFT (16)
+#define OMAP_I2C4_PRM_VALID_MSK (1<<24)
+
struct omap_i2c_dev {
struct device *dev;
void __iomem *base; /* virtual */
@@ -524,7 +531,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
return -EIO;
}
-
/*
* Prepare controller for a transaction and call omap_i2c_xfer_msg
* to do the work during IRQ processing.
@@ -561,6 +567,70 @@ omap_i2c_func(struct i2c_adapter *adap)
return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
}
+/*
+ * I2C4 is a special I2C controller unlike I2C1, I2C2 and I2C3.
+ * Prepare controller for a transaction and write into appropriate
+ * registers for transferring data. Only writes are supported on I2C4.
+ */
+static int omap_i2c4_xfer_msg(struct i2c_adapter *adap,
+ struct i2c_msg *msg, int stop)
+{
+ struct omap_i2c_dev *dev = i2c_get_adapdata(adap);
+ unsigned int r;
+ unsigned char *cptr;
+ unsigned char regval, dataval;
+
+ dev_dbg(dev->dev, "I2C4:addr: 0x%04x, len: %d,flags: 0x%x,stop: %d\n",
+ msg->addr, msg->len, msg->flags, stop);
+
+ if (msg->len == 0)
+ return -EINVAL;
+
+ dev->buf_len = msg->len;
+
+ cptr = msg->buf;
+ regval = *cptr;
+ cptr++;
+ dataval = *cptr;
+
+ r = (((msg->addr) & OMAP_I2C4_PRM_SLAVE_ADDR_MSK) |
+ (regval << OMAP_I2C4_PRM_REG_SHIFT) |
+ (dataval << OMAP_I2C4_PRM_DATA_SHIFT) |
+ OMAP_I2C4_PRM_VALID_MSK);
+
+ regval = *(volatile unsigned int *)OMAP_I2C4_PRM_VC_BYPASS_VAL;
+
+ while (regval & OMAP_I2C4_PRM_VALID_MSK)
+ regval = *(volatile unsigned int *)OMAP_I2C4_PRM_VC_BYPASS_VAL;
+
+ *(volatile unsigned int *)OMAP_I2C4_PRM_VC_BYPASS_VAL = r;
+ return 0;
+}
+
+/*
+ * I2C4 is a special I2C controller unlike I2C1, I2C2 and I2C3.
+ * Prepare controller for a transaction and call omap_i2c4_xfer_msg
+ * to do the work during IRQ processing.
+ * Only writes are supported on I2C4.
+ */
+static int
+omap_i2c4_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+{
+ int i;
+ int r;
+
+ for (i = 0; i < num; i++) {
+ r = omap_i2c4_xfer_msg(adap, &msgs[i], (i == (num - 1)));
+ if (r != 0)
+ break;
+ }
+
+ if (r == 0)
+ return num;
+ return r;
+}
+
+
static inline void
omap_i2c_complete_cmd(struct omap_i2c_dev *dev, u16 err)
{
@@ -761,6 +831,11 @@ omap_i2c_isr(int this_irq, void *dev_id)
return count ? IRQ_HANDLED : IRQ_NONE;
}
+static const struct i2c_algorithm omap_i2c4_algo = {
+ .master_xfer = omap_i2c4_xfer,
+ .functionality = omap_i2c_func,
+};
+
static const struct i2c_algorithm omap_i2c_algo = {
.master_xfer = omap_i2c_xfer,
.functionality = omap_i2c_func,
@@ -839,8 +914,8 @@ omap_i2c_probe(struct platform_device *pdev)
*/
dev->fifo_size = (dev->fifo_size / 2);
dev->b_hw = 1; /* Enable hardware fixes */
- }
+ }
/* reset ASAP, clearing any IRQs */
omap_i2c_init(dev);
@@ -856,13 +931,14 @@ omap_i2c_probe(struct platform_device *pdev)
pdev->id, dev->rev >> 4, dev->rev & 0xf, dev->speed);
omap_i2c_idle(dev);
-
adap = &dev->adapter;
i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON;
strncpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));
+ /* if BusId is 1-3 then algorithm is omap_i2c_algo */
adap->algo = &omap_i2c_algo;
+
adap->dev.parent = &pdev->dev;
/* i2c device drivers may be active on return from add_adapter() */
@@ -911,6 +987,61 @@ omap_i2c_remove(struct platform_device *pdev)
return 0;
}
+static int __init
+omap_i2c4_probe(struct platform_device *pdev)
+{
+ struct omap_i2c_dev *dev;
+ struct i2c_adapter *adap;
+ int r = 0;
+ u32 *speed = NULL;
+
+ dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL);
+ if (!dev)
+ r = -ENOMEM;
+
+ if (pdev->dev.platform_data != NULL)
+ speed = (u32 *) pdev->dev.platform_data;
+ else
+ *speed = 100; /* Defualt speed */
+
+ dev->speed = *speed;
+ dev->idle = 1;
+ dev->dev = &pdev->dev;
+
+ platform_set_drvdata(pdev, dev);
+
+ r = omap_i2c_get_clocks(dev);
+
+ adap = &dev->adapter;
+ i2c_set_adapdata(adap, dev);
+ adap->owner = THIS_MODULE;
+ adap->class = I2C_CLASS_HWMON;
+ strncpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));
+ /* BusId is 4(I2C4) then algorithm is different */
+ adap->algo = &omap_i2c4_algo;
+
+ adap->dev.parent = &pdev->dev;
+
+ /* i2c device drivers may be active on return from add_adapter() */
+ adap->nr = pdev->id;
+ r = i2c_add_numbered_adapter(adap);
+ if (r)
+ dev_err(dev->dev, "failure adding adapter\n");
+
+ return r;
+}
+
+static int
+omap_i2c4_remove(struct platform_device *pdev)
+{
+ struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
+ platform_set_drvdata(pdev, NULL);
+ i2c_del_adapter(&dev->adapter);
+ kfree(dev);
+ return 0;
+}
+
+
static struct platform_driver omap_i2c_driver = {
.probe = omap_i2c_probe,
.remove = omap_i2c_remove,
@@ -920,17 +1051,32 @@ static struct platform_driver omap_i2c_driver = {
},
};
+static struct platform_driver omap_i2c4_driver = {
+ .probe = omap_i2c4_probe,
+ .remove = omap_i2c4_remove,
+ .driver = {
+ .name = "i2c4_omap",
+ .owner = THIS_MODULE,
+ },
+};
+
+
/* I2C may be needed to bring up other drivers */
static int __init
omap_i2c_init_driver(void)
{
- return platform_driver_register(&omap_i2c_driver);
+ int ret = 0;
+ ret = platform_driver_register(&omap_i2c_driver);
+ ret = platform_driver_register(&omap_i2c4_driver);
+
+ return ret;
}
subsys_initcall(omap_i2c_init_driver);
static void __exit omap_i2c_exit_driver(void)
{
platform_driver_unregister(&omap_i2c_driver);
+ platform_driver_unregister(&omap_i2c4_driver);
}
module_exit(omap_i2c_exit_driver);
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index d61589b..5702520 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -194,6 +194,29 @@ config SENSORS_MAX6875
This driver can also be built as a module. If so, the module
will be called max6875.
+choice
+ prompt "TPS6235X driver support"
+ depends on I2C=y && PR785=y
+ default n
+ help
+ nothing.
+
+ config TPS6235X_I2C2
+ bool "TPS6235X_I2C2"
+ help
+ Say yes here if you have TPS6235x devices connected to I2C Bus2
+ on PR785 Power module. Note that while selecting this option,
+ TPS6235X_I2C4 should not be selected.
+
+ config TPS6235X_I2C4
+ bool "TPS6235X_I2C4"
+ help
+ Say yes here if you have TPS6235x devices connected to I2C Bus4
+ on PR785 Power module. Note that while selecting this option,
+ TPS6235X_I2C2 should not be selected.
+
+endchoice
+
config SENSORS_TSL2550
tristate "Taos TSL2550 ambient light sensor"
depends on EXPERIMENTAL
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 0765389..6a827e5 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -80,4 +80,11 @@ config REGULATOR_DA903X
Say y here to support the BUCKs and LDOs regulators found on
Dialog Semiconductor DA9030/DA9034 PMIC.
+config REGULATOR_TPS6235X
+ bool "TPS6235X Power regulator for OMAP3EVM"
+ depends on PR785
+ help
+ This driver supports the voltage regulators provided by TPS6235x chips.
+ The TPS62352 and TPS62353 are mounted on PR785 Power module card for
+ providing voltage regulator functions.
endif
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 0dacb18..fdc5f5b 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -12,5 +12,6 @@ obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
+obj-$(CONFIG_REGULATOR_TPS6235X)+= tps6235x-regulator.o
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 02a7744..901f402 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -30,33 +30,6 @@ static LIST_HEAD(regulator_list);
static LIST_HEAD(regulator_map_list);
/**
- * struct regulator_dev
- *
- * Voltage / Current regulator class device. One for each regulator.
- */
-struct regulator_dev {
- struct regulator_desc *desc;
- int use_count;
-
- /* lists we belong to */
- struct list_head list; /* list of all regulators */
- struct list_head slist; /* list of supplied regulators */
-
- /* lists we own */
- struct list_head consumer_list; /* consumers we supply */
- struct list_head supply_list; /* regulators we supply */
-
- struct blocking_notifier_head notifier;
- struct mutex mutex; /* consumer lock */
- struct module *owner;
- struct device dev;
- struct regulation_constraints *constraints;
- struct regulator_dev *supply; /* for tree */
-
- void *reg_data; /* regulator_dev data */
-};
-
-/**
* struct regulator_map
*
* Used to provide symbolic supply names to devices.
diff --git a/drivers/regulator/tps6235x-regulator.c b/drivers/regulator/tps6235x-regulator.c
new file mode 100644
index 0000000..8a900db
--- /dev/null
+++ b/drivers/regulator/tps6235x-regulator.c
@@ -0,0 +1,544 @@
+/*
+ * tps6235x-regulator.c -- support regulators in tps6235x family chips
+ *
+ * Copyright (C) 2008 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/regulator/consumer.h>
+
+/* Minimum and Maximum dc-dc voltage supported by the TPS6235x devices
+All voltages given in millivolts */
+#define PR785_MIN_CORE_VOLT 750
+#define PR785_MAX_CORE_VOLT 1537
+#define PR785_MIN_MPU_VOLT 750
+#define PR785_MAX_MPU_VOLT 1537
+
+/* Maximum number of bytes to be read in a single read */
+#define PR785_RETRY_COUNT 0x3
+
+/* Register bit settings */
+#define TPS6235X_EN_DCDC (0x1 << 0x7)
+#define TPS6235X_VSM_MSK (0x3F)
+#define TPS6235X_EN_SYN_MSK (0x1 << 0x5)
+#define TPS6235X_SW_VOLT_MSK (0x1 << 0x4)
+#define TPS6235X_PWR_OK_MSK (0x1 << 0x5)
+#define TPS6235X_OUT_DIS_MSK (0x1 << 0x6)
+#define TPS6235X_GO_MSK (0x1 << 0x7)
+
+/*
+ * These chips are often used in OMAP-based systems.
+ *
+ * This driver implements software-based resource control for various
+ * voltage regulators. This is usually augmented with state machine
+ * based control.
+ */
+struct tps_6235x_info {
+ unsigned int state;
+ unsigned int tps_i2c_addr;
+ struct i2c_client *client;
+ struct device *i2c_dev;
+ /* platform data holder */
+ void *pdata;
+};
+
+static struct tps_6235x_info tps_6235x_infodata[2];
+
+
+#ifndef REGULATOR_MODE_OFF
+#define REGULATOR_MODE_OFF 0
+#endif
+
+
+/* LDO control registers ... offset is from the base of its register bank.
+ * The first three registers of all power resource banks help hardware to
+ * manage the various resource groups.
+ */
+
+#define TPS6235X_REG_VSEL0 0
+#define TPS6235X_REG_VSEL1 1
+#define TPS6235X_REG_CTRL1 2
+#define TPS6235X_REG_CTRL2 3
+#define TPS6235X_REG_MAX TPS6235X_REG_CTRL2
+
+#define MODULE_NAME "tps6235x_power"
+
+/* Debug functions */
+#ifdef DEBUG
+
+#define dump_reg(client, reg, val) \
+ do { \
+ tps6235x_read_reg(client, reg, &val); \
+ dev_dbg(&(client)->dev, "Reg(0x%.2X): 0x%.2X\n", reg, val); \
+ } while (0)
+
+#endif /* #ifdef DEBUG */
+
+/* Device addresses for PR785 card */
+#define PR785_62352_CORE_ADDR 0x4A
+#define PR785_62353_MPU_ADDR 0x48
+
+/* Minimum and Maximum dc-dc voltage supported by the TPS6235x devices
+All voltages given in millivolts */
+#define PR785_MIN_CORE_VOLT 750
+#define PR785_MAX_CORE_VOLT 1537
+#define PR785_MIN_MPU_VOLT 750
+#define PR785_MAX_MPU_VOLT 1537
+
+/* Maximum number of bytes to be read in a single read */
+#define PR785_RETRY_COUNT 0x3
+
+/* Register bit settings */
+#define TPS6235X_EN_DCDC (0x1 << 0x7)
+#define TPS6235X_VSM_MSK (0x3F)
+#define TPS6235X_EN_SYN_MSK (0x1 << 0x5)
+#define TPS6235X_SW_VOLT_MSK (0x1 << 0x4)
+#define TPS6235X_PWR_OK_MSK (0x1 << 0x5)
+#define TPS6235X_OUT_DIS_MSK (0x1 << 0x6)
+#define TPS6235X_GO_MSK (0x1 << 0x7)
+
+int pr785_enbl_dcdc(unsigned char tps_mod_type, unsigned int en_flag);
+int pr785_get_dcdc_volt(unsigned char tps_mod_type, unsigned int *millivolts);
+int pr785_set_dcdc_volt(unsigned char tps_mod_type, unsigned int millivolts);
+
+static int tps6235x_dcdc_is_enabled(struct regulator_dev *dev)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+ return tps_info->state;
+}
+
+static int tps6235x_dcdc_enable(struct regulator_dev *dev)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+
+ tps_info->state = 1;
+ return pr785_enbl_dcdc(tps_info->tps_i2c_addr, 1);
+}
+
+static int tps6235x_dcdc_disable(struct regulator_dev *dev)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+
+ tps_info->state = 0;
+ return pr785_enbl_dcdc(tps_info->tps_i2c_addr, 0);
+}
+
+static int tps6235x_dcdc_get_voltage(struct regulator_dev *dev)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+ unsigned int millivolts;
+
+ pr785_get_dcdc_volt(tps_info->tps_i2c_addr, &millivolts);
+ return millivolts * 1000;
+}
+
+static int tps6235x_dcdc_set_voltage(struct regulator_dev *dev,
+ int min_uV, int max_uV)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+ unsigned int millivolts = max_uV / 1000;
+
+ return pr785_set_dcdc_volt(tps_info->tps_i2c_addr, millivolts) ;
+}
+
+
+static struct regulator_ops tps62352_dcdc_ops = {
+ .is_enabled = tps6235x_dcdc_is_enabled,
+ .get_voltage = tps6235x_dcdc_get_voltage,
+ .set_voltage = tps6235x_dcdc_set_voltage,
+};
+
+static struct regulator_ops tps62353_dcdc_ops = {
+ .is_enabled = tps6235x_dcdc_is_enabled,
+ .enable = tps6235x_dcdc_enable,
+ .disable = tps6235x_dcdc_disable,
+ .get_voltage = tps6235x_dcdc_get_voltage,
+ .set_voltage = tps6235x_dcdc_set_voltage,
+};
+
+
+static struct regulator_desc regulators[] = {
+ {
+ .name = "tps62352",
+ .id = 2,
+ .ops = &tps62352_dcdc_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "tps62353",
+ .id = 3,
+ .ops = &tps62353_dcdc_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int tps6235xreg_probe(struct platform_device *pdev)
+{
+ struct tps_6235x_info *info;
+ struct regulator_dev *rdev = NULL;
+
+ info = &tps_6235x_infodata[(pdev->id-2)];
+
+ rdev = regulator_register(&regulators[(pdev->id-2)], &pdev->dev, info);
+ if (rdev == NULL)
+ printk(KERN_ERR "err in regulator registry = %d\n", pdev->id);
+
+ platform_set_drvdata(pdev, rdev);
+
+ return 0;
+}
+
+static int __devexit tps6235xreg_remove(struct platform_device *pdev)
+{
+ regulator_unregister(platform_get_drvdata(pdev));
+ return 0;
+}
+
+MODULE_ALIAS("platform:tps6235x_reg");
+
+static struct platform_driver tps6235xreg_driver = {
+ .probe = tps6235xreg_probe,
+ .remove = __devexit_p(tps6235xreg_remove),
+ .driver.name = "tps6235x_reg",
+ .driver.owner = THIS_MODULE,
+};
+
+static int __init tps6235xreg_init(void)
+{
+ return platform_driver_register(&tps6235xreg_driver);
+}
+late_initcall(tps6235xreg_init);
+
+static void __exit tps6235xreg_exit(void)
+{
+ platform_driver_unregister(&tps6235xreg_driver);
+}
+module_exit(tps6235xreg_exit)
+
+MODULE_DESCRIPTION("TPS6235X regulator driver");
+MODULE_LICENSE("GPL");
+
+
+/*
+ * Get client pointer for a particular device
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static struct i2c_client *tps_6235x_get_client(unsigned char tps_i2c_addr)
+{
+ if (tps_i2c_addr == PR785_62352_CORE_ADDR)
+ return tps_6235x_infodata[0].client;
+ else if (tps_i2c_addr == PR785_62353_MPU_ADDR)
+ return tps_6235x_infodata[1].client;
+ else
+ return NULL;
+}
+
+/*
+ * Read a value from a register in an tps_6235x device.
+ * The value is returned in 'val'.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int tps_6235x_read_reg(struct i2c_client *client, u8 reg, u8 *val)
+{
+ u8 data;
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ data = i2c_smbus_read_byte_data(client, reg);
+ *val = data;
+ return 0;
+}
+
+/*
+ * Write a value to a register in an tps_6235x device.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int tps_6235x_write_reg(struct i2c_client *client, u8 reg, u8 val)
+{
+ int err;
+ int retry = 0;
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ err = i2c_smbus_write_byte_data(client, reg, val);
+ if (err >= 0)
+ return 0;
+
+ dev_err(&client->dev,
+ "wrote 0x%.2x to offset 0x%.2x error %d\n", val, reg, err);
+
+ if (retry <= PR785_RETRY_COUNT) {
+ dev_info(&client->dev, "retry ... %d\n", retry);
+ retry++;
+ schedule_timeout(msecs_to_jiffies(20));
+ goto again;
+ }
+ return err;
+}
+
+
+/**
+* pwr_i2c_read - Allows the caller to read one register from TPS device
+* based on the address given. For the PR785 it reads
+* only 1 byte into a specified register
+* tps_mod_type - Enum for the device to be read
+* reg - Register to be read from(value has to be between 0-3
+* val - value read from the reg
+* Retval - 0 -> Success else non-zero
+**/
+int pwr_i2c_read(unsigned char tps_mod_type, u8 reg, u8 *val)
+{
+ struct i2c_client *client;
+
+ client = tps_6235x_get_client(tps_mod_type);
+ /* check if register is less than <= 3 Register is 0 -3 */
+ if (reg > TPS6235X_REG_MAX)
+ return -1;
+
+ return tps_6235x_read_reg(client, reg, val);
+}
+EXPORT_SYMBOL(pwr_i2c_read);
+
+/**
+* pwr_i2c_write - Allows the caller to write one register from TPS device
+* based on the address given. For the PR785 it writes
+* only 1 byte into a specified register
+* tps_mod_type - Enum for the device to be written
+* reg - Register to be written to(value has to be between 0-3
+* val - value to be written to reg
+* Retval - 0 -> Success else non-zero
+**/
+int pwr_i2c_write(unsigned char tps_mod_type, u8 reg, u8 val)
+{
+ struct i2c_client *client;
+
+ client = tps_6235x_get_client(tps_mod_type);
+
+ /* check if register is less than <= 3 Register is 0 -3 */
+ if (reg > TPS6235X_REG_MAX)
+ return -1;
+
+ return tps_6235x_write_reg(client, reg, val);
+}
+EXPORT_SYMBOL(pwr_i2c_write);
+
+
+/**
+* TPSPR785 - Specific functions
+* pr785_enbl_dcdc - Allows the caller to enable or disable the TPS6235x device
+* on the PR785 board. The voltage for PR785 is selected by
+* VSEL1 register since VSEL pin is kept high
+*
+* flag - 1 == enable 0 == disable
+* Retval - 0 -> Success else non-zero
+**/
+int pr785_enbl_dcdc(unsigned char tps_mod_type, unsigned int en_flag)
+{
+ unsigned char vsel1;
+ int ret;
+
+ ret = pwr_i2c_read(tps_mod_type, TPS6235X_REG_VSEL1, &vsel1);
+ if (ret == 0) {
+ if (en_flag)
+ vsel1 |= TPS6235X_EN_DCDC;
+ else
+ vsel1 &= ~(TPS6235X_EN_DCDC);
+ ret = pwr_i2c_write(tps_mod_type, TPS6235X_REG_VSEL1, vsel1);
+ }
+ return ret;
+}
+EXPORT_SYMBOL(pr785_enbl_dcdc);
+
+/**
+* TPSPR785 - Specific functions
+* pr785_set_dcdc_volt - Allows the caller to set a particular voltage on
+* for CORE or MPU
+*
+* voltage - voltage to be set in millivolts (75--1537)
+* Retval - 0 -> Success else non-zero
+**/
+int pr785_set_dcdc_volt(unsigned char tps_mod_type, unsigned int millivolts)
+{
+ unsigned char vsel1;
+ unsigned int volt;
+
+ /* check if the millivolts is within range */
+ if ((millivolts < PR785_MIN_CORE_VOLT) ||
+ (millivolts > PR785_MAX_CORE_VOLT))
+ return -1;
+
+ /* Output voltage set is = min_op_volt + ( VSM * 12.5mv) */
+ volt = millivolts - PR785_MIN_CORE_VOLT;
+ volt /= 25;
+ volt *= 2;
+ vsel1 = ((TPS6235X_EN_DCDC) | (volt & TPS6235X_VSM_MSK));
+ return pwr_i2c_write(tps_mod_type, TPS6235X_REG_VSEL1, vsel1);
+}
+EXPORT_SYMBOL(pr785_set_dcdc_volt);
+
+/**
+* TPSPR785 - Specific functions
+* pr785_get_dcdc_volt - Allows the caller to get the set voltage on a
+* particular TPS 6235x device on PR785 card
+*
+* voltage - voltage to be set in millivolts (75--1537)
+* Retval - 0 -> Success else non-zero
+**/
+int pr785_get_dcdc_volt(unsigned char tps_mod_type, unsigned int *millivolts)
+{
+ unsigned char vsel1;
+ unsigned int volt;
+
+ /* Read the VSEL1 register to get VSM */
+ pwr_i2c_read(tps_mod_type, TPS6235X_REG_VSEL1, &vsel1);
+ /* Output voltage set is = min_op_volt + ( VSM * 12.5mv) */
+ /* To cut out floating point operation we will multiply by 25
+ divide by 2 */
+ volt = (((vsel1 & TPS6235X_VSM_MSK) * 25) / 2) + PR785_MIN_CORE_VOLT;
+ *millivolts = volt;
+ return 0;
+}
+EXPORT_SYMBOL(pr785_get_dcdc_volt);
+
+/**
+ * tps_6235x_probe - TPS6235x driver i2c probe handler
+ *
+ * Register PR785 as an i2c client device driver
+ */
+static struct i2c_driver tps_6235x_i2c_driver;
+
+static
+int tps_6235x_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ unsigned char reg_val;
+
+ printk(KERN_INFO "tps_6235x_probe:i2c_addr = %x\n", (int)client->addr);
+
+ /* Device probed is TPS62352 CORE pwr chip if driver_data = 0
+ Device probed is TPS62353 MPU pwr chip if driver_data = 1 */
+ tps_6235x_infodata[id->driver_data].client = client;
+ tps_6235x_infodata[id->driver_data].tps_i2c_addr = client->addr;
+ tps_6235x_infodata[id->driver_data].state = 1;
+ tps_6235x_infodata[id->driver_data].i2c_dev = &client->dev;
+
+ tps_6235x_read_reg(client, TPS6235X_REG_CTRL2, &reg_val);
+ reg_val |= (TPS6235X_OUT_DIS_MSK | TPS6235X_GO_MSK);
+ tps_6235x_write_reg(client, TPS6235X_REG_CTRL2, reg_val);
+ tps_6235x_read_reg(client, TPS6235X_REG_CTRL2, &reg_val);
+
+ i2c_set_clientdata(client, &tps_6235x_infodata[id->driver_data]);
+
+ if (reg_val & TPS6235X_PWR_OK_MSK)
+ printk(KERN_INFO "Power is OK %x\n", reg_val);
+ else
+ printk(KERN_INFO "Power not within range = %x\n", reg_val);
+ return 0;
+}
+
+/**
+ * tps_6235x_remove - TPS6235x driver i2c remove handler
+ *
+ * UnregisterPR785 as an i2c client device driver
+ */
+static int __exit tps_6235x_remove(struct i2c_client *client)
+{
+#ifdef DEBUG
+ printk(KERN_INFO "tps_6235x_remove invoked\n");
+#endif
+
+ if (!client->adapter)
+ return -ENODEV; /* our client isn't attached */
+
+ i2c_set_clientdata(client, NULL);
+
+ return 0;
+}
+
+
+static const struct i2c_device_id tps_6235x_id[] = {
+ { "tps62352", 0},
+ { "tps62353", 1},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, tps_6235x_id);
+
+static struct i2c_driver tps_6235x_i2c_driver = {
+ .driver = {
+ .name = MODULE_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = tps_6235x_probe,
+ .remove = __exit_p(tps_6235x_remove),
+ .id_table = tps_6235x_id,
+};
+
+/**
+ * tps_6235x_init
+ *
+ * Module init function
+ */
+static int __init tps_6235x_init(void)
+{
+ int err;
+
+#ifdef DEBUG
+ printk(KERN_INFO "tps_6235x_init invoked\n");
+#endif
+
+ err = i2c_add_driver(&tps_6235x_i2c_driver);
+ if (err) {
+ printk(KERN_ERR "Failed to register " MODULE_NAME ".\n");
+ return err;
+ } else
+ printk(KERN_INFO "I2c driver registered\n");
+
+ return 0;
+}
+
+/**
+ * tps_6235x_cleanup
+ *
+ * Module exit function
+ */
+static void __exit tps_6235x_cleanup(void)
+{
+#ifdef DEBUG
+ printk(KERN_INFO "tps_6235x_cleanup invoked\n");
+#endif
+ i2c_del_driver(&tps_6235x_i2c_driver);
+}
+
+late_initcall(tps_6235x_init);
+module_exit(tps_6235x_cleanup);
+
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("TPS6235x based PR785 linux driver");
+MODULE_LICENSE("GPL");
+
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index e37d805..9107344 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -18,9 +18,30 @@
#include <linux/device.h>
#include <linux/regulator/consumer.h>
-struct regulator_dev;
struct regulator_init_data;
+struct regulator_dev {
+ struct regulator_desc *desc;
+ int use_count;
+
+ /* lists we belong to */
+ struct list_head list; /* list of all regulators */
+ struct list_head slist; /* list of supplied regulators */
+
+ /* lists we own */
+ struct list_head consumer_list; /* consumers we supply */
+ struct list_head supply_list; /* regulators we supply */
+
+ struct blocking_notifier_head notifier;
+ struct mutex mutex; /* consumer lock */
+ struct module *owner;
+ struct device dev;
+ struct regulation_constraints *constraints;
+ struct regulator_dev *supply; /* for tree */
+
+ void *reg_data; /* regulator_dev data */
+};
+
/**
* struct regulator_ops - regulator operations.
*
--
1.5.6
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
More majordomo info at http://vger.kernel.org/majordomo-info.html
--
balbi
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Pillai, Manikandan
2008-12-04 11:35:26 UTC
Permalink
Hi,

Pls find comments inlined.

regards


-----Original Message-----
From: Felipe Balbi [mailto:***@nokia.com]
Sent: Thursday, December 04, 2008 4:49 PM
To: ext ***@india.ti.com
Cc: linux-***@vger.kernel.org; Pillai, Manikandan
Subject: Re: [PATCH 2/2] Putting TPS6235x into the power regulator framework
Post by y***@india.ti.com
This patch moves the TPS6235x drivers from the drivers/i2c to drivers/
regulator to put the TPS6235x drivers under the power regulator framework
suffix core_pwr and mpu_pwr has been removed
I2C bus speeds replaced with numbers again
Camel case has been removed
TPS moved into regulator framework and drivers/i2c/chips left untouched.
Not clear on how to implement runtime check for PR785 and would require some
inputs on implementing the same.
This patch should be broken into smaller pieces.
[Pillai, Manikandan] OK

The tps driver should come separated, drivers/regulator/core.c should go
to the maintainer in a separate patch, i2c-omap.c adding the i2c4
support, should be in a separate patch and Ccing Ben Dooks and Jean
Delvare.
[Pillai, Manikandan] In core.c, I am just moving the definition of a struct to
the header file.

More comments below.
Post by y***@india.ti.com
---
arch/arm/mach-omap2/board-omap3evm.c | 6 +-
arch/arm/plat-omap/devices.c | 78 +++++
arch/arm/plat-omap/i2c.c | 21 +-
drivers/i2c/busses/i2c-omap.c | 154 +++++++++-
drivers/i2c/chips/Kconfig | 23 ++
drivers/regulator/Kconfig | 7 +
drivers/regulator/Makefile | 1 +
drivers/regulator/core.c | 27 --
drivers/regulator/tps6235x-regulator.c | 544 ++++++++++++++++++++++++++++++++
include/linux/regulator/driver.h | 23 ++-
10 files changed, 848 insertions(+), 36 deletions(-)
create mode 100644 drivers/regulator/tps6235x-regulator.c
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 22ac2e9..ab3070d 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -168,7 +168,7 @@ static struct i2c_board_info __initdata tps_6235x_i2c_board_info[] = {
static int __init omap3_evm_i2c_init(void)
{
-#if defined(CONFIG_PR785)
+#if defined(CONFIG_PR785) && defined(CONFIG_TPS6235X_I2C2)
omap_register_i2c_bus(1, 2600, tps_6235x_i2c_board_info,
ARRAY_SIZE(tps_6235x_i2c_board_info));
#endif
@@ -178,6 +178,10 @@ static int __init omap3_evm_i2c_init(void)
#endif
omap_register_i2c_bus(2, 400, NULL, 0);
omap_register_i2c_bus(3, 400, NULL, 0);
+#if defined(CONFIG_PR785) && defined(CONFIG_TPS6235X_I2C4)
+ omap_register_i2c_bus(4, 2600, tps_6235x_i2c_board_info,
+ ARRAY_SIZE(tps_6235x_i2c_board_info));
+#endif
heh, i thought bus4 wasn't sw controllable :-s

[Pillai, Manikandan] Bus 4 can be used to write from master. It cannot be used to read.
Post by y***@india.ti.com
return 0;
}
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 25c6d10..4c81eaf 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -27,6 +27,7 @@
#include <mach/gpio.h>
#include <mach/dsp_common.h>
#include <mach/mcbsp.h>
+#include <linux/regulator/machine.h>
#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
@@ -350,6 +351,83 @@ static void omap_init_rng(void)
static inline void omap_init_rng(void) {}
#endif
+/*-------------------------------------------------------------------------*/
+#if defined(CONFIG_PR785) || defined(CONFIG_PR785_MODULE)
+
+static struct regulator_init_data tps_regulator_data[];
+
+static struct resource tps6235x_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ },
+};
this is not the correct place for it as only one board has this driver.
Move it to the proper board-file.

[Pillai, Manikandan] I will move it to board-omap3evm.c
Post by y***@india.ti.com
+
+static struct platform_device omap_tps6235x_device[] = {
+ {
+ .name = "tps6235x_reg",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(tps6235x_resources),
+ .resource = tps6235x_resources,
+ .dev = {
+ .platform_data = &tps_regulator_data[0],
+ },
+ },
+ {
+ .name = "tps6235x_reg",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(tps6235x_resources),
+ .resource = tps6235x_resources,
+ .dev = {
+ .platform_data = &tps_regulator_data[1],
+ },
+ },
+};
+
+static struct regulator_consumer_supply tps6235x_consumers[] = {
+ {
+ .dev = &omap_tps6235x_device[0].dev,
+ .supply = "tps62352",
+ },
+ {
+ .dev = &omap_tps6235x_device[1].dev,
+ .supply = "tps62353",
supply should be Vdd, or Vbus or something more useful, not the chip's
name.
[Pillai, Manikandan] Shall make it vdd1 and vdd2 and map it exactly as in
OMAP spec.
Post by y***@india.ti.com
+ },
+};
+
+static struct regulator_init_data tps_regulator_data[] = {
+ {
+ .constraints = {
+ .min_uV = 750000,
+ .max_uV = 1537000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &tps6235x_consumers[0],
+ },
+ {
+ .constraints = {
+ .min_uV = 750000,
+ .max_uV = 1537000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &tps6235x_consumers[1],
+ },
+
+};
+
+static void omap_init_pr785(void)
+{
+ (void) platform_device_register(&omap_tps6235x_device[0]);
+ (void) platform_device_register(&omap_tps6235x_device[1]);
+}
+#else
+static inline void omap_init_pr785(void) {}
+#endif
+/*-------------------------------------------------------------------------*/
+
/*
* This gets called after board-specific INIT_MACHINE, and initializes most
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index 89a6ab0..e0c763a 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -35,6 +35,7 @@
#define OMAP2_I2C_BASE3 0x48060000
static const char name[] = "i2c_omap";
+static const char name4[] = "i2c4_omap";
#define I2C_RESOURCE_BUILDER(base, irq) \
{ \
@@ -54,6 +55,7 @@ static struct resource i2c_resources[][2] = {
#endif
#if defined(CONFIG_ARCH_OMAP34XX)
{ I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, INT_34XX_I2C3_IRQ) },
+ { I2C_RESOURCE_BUILDER(0x0, 0x0) },
#endif
};
@@ -68,6 +70,17 @@ static struct resource i2c_resources[][2] = {
}, \
}
+#define I2C_DEV_BUILDER4(bus_id, res, data) \
+ { \
+ .id = (bus_id), \
+ .name = name4, \
+ .num_resources = ARRAY_SIZE(res), \
+ .resource = (res), \
+ .dev = { \
+ .platform_data = (data), \
+ }, \
+ }
+
static u32 i2c_rate[ARRAY_SIZE(i2c_resources)];
static struct platform_device omap_i2c_devices[] = {
I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_rate[0]),
@@ -76,6 +89,7 @@ static struct platform_device omap_i2c_devices[] = {
#endif
#if defined(CONFIG_ARCH_OMAP34XX)
I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_rate[2]),
+ I2C_DEV_BUILDER4(4, i2c_resources[3], &i2c_rate[3]),
#endif
};
@@ -132,7 +146,8 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
else if (cpu_is_omap24xx())
ports = 2;
else if (cpu_is_omap34xx())
- ports = 3;
+ /* There are 4 I2C controller on OMAP3 */
+ ports = 4;
BUG_ON(bus_id < 1 || bus_id > ports);
@@ -141,7 +156,6 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
if (err)
return err;
}
-
pdev = &omap_i2c_devices[bus_id - 1];
*(u32 *)pdev->dev.platform_data = clkrate;
@@ -159,6 +173,7 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
res[1].start = irq;
}
- omap_i2c_mux_pins(bus_id - 1);
+ if (bus_id != 4)
+ omap_i2c_mux_pins(bus_id - 1);
return platform_device_register(pdev);
}
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 96f3bed..bf8dd1e 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -157,6 +157,13 @@
#define SYSC_CLOCKACTIVITY_FCLK 0x2
+/* I2C4 Programming interface register address */
+#define OMAP_I2C4_PRM_VC_BYPASS_VAL (IO_ADDRESS(0x4830723C))
+#define OMAP_I2C4_PRM_SLAVE_ADDR_MSK (0x7F)
+#define OMAP_I2C4_PRM_REG_SHIFT (8)
+#define OMAP_I2C4_PRM_DATA_SHIFT (16)
+#define OMAP_I2C4_PRM_VALID_MSK (1<<24)
+
struct omap_i2c_dev {
struct device *dev;
void __iomem *base; /* virtual */
@@ -524,7 +531,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
return -EIO;
}
-
/*
* Prepare controller for a transaction and call omap_i2c_xfer_msg
* to do the work during IRQ processing.
@@ -561,6 +567,70 @@ omap_i2c_func(struct i2c_adapter *adap)
return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
}
+/*
+ * I2C4 is a special I2C controller unlike I2C1, I2C2 and I2C3.
+ * Prepare controller for a transaction and write into appropriate
+ * registers for transferring data. Only writes are supported on I2C4.
+ */
+static int omap_i2c4_xfer_msg(struct i2c_adapter *adap,
+ struct i2c_msg *msg, int stop)
+{
+ struct omap_i2c_dev *dev = i2c_get_adapdata(adap);
+ unsigned int r;
+ unsigned char *cptr;
+ unsigned char regval, dataval;
+
+ dev_dbg(dev->dev, "I2C4:addr: 0x%04x, len: %d,flags: 0x%x,stop: %d\n",
+ msg->addr, msg->len, msg->flags, stop);
+
+ if (msg->len == 0)
+ return -EINVAL;
+
+ dev->buf_len = msg->len;
+
+ cptr = msg->buf;
+ regval = *cptr;
+ cptr++;
+ dataval = *cptr;
+
+ r = (((msg->addr) & OMAP_I2C4_PRM_SLAVE_ADDR_MSK) |
+ (regval << OMAP_I2C4_PRM_REG_SHIFT) |
+ (dataval << OMAP_I2C4_PRM_DATA_SHIFT) |
+ OMAP_I2C4_PRM_VALID_MSK);
+
+ regval = *(volatile unsigned int *)OMAP_I2C4_PRM_VC_BYPASS_VAL;
+
+ while (regval & OMAP_I2C4_PRM_VALID_MSK)
+ regval = *(volatile unsigned int *)OMAP_I2C4_PRM_VC_BYPASS_VAL;
+
+ *(volatile unsigned int *)OMAP_I2C4_PRM_VC_BYPASS_VAL = r;
+ return 0;
+}
+
+/*
+ * I2C4 is a special I2C controller unlike I2C1, I2C2 and I2C3.
+ * Prepare controller for a transaction and call omap_i2c4_xfer_msg
+ * to do the work during IRQ processing.
+ * Only writes are supported on I2C4.
+ */
+static int
+omap_i2c4_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+{
+ int i;
+ int r;
+
+ for (i = 0; i < num; i++) {
+ r = omap_i2c4_xfer_msg(adap, &msgs[i], (i == (num - 1)));
+ if (r != 0)
+ break;
+ }
+
+ if (r == 0)
+ return num;
+ return r;
+}
+
+
static inline void
omap_i2c_complete_cmd(struct omap_i2c_dev *dev, u16 err)
{
@@ -761,6 +831,11 @@ omap_i2c_isr(int this_irq, void *dev_id)
return count ? IRQ_HANDLED : IRQ_NONE;
}
+static const struct i2c_algorithm omap_i2c4_algo = {
+ .master_xfer = omap_i2c4_xfer,
+ .functionality = omap_i2c_func,
+};
+
static const struct i2c_algorithm omap_i2c_algo = {
.master_xfer = omap_i2c_xfer,
.functionality = omap_i2c_func,
@@ -839,8 +914,8 @@ omap_i2c_probe(struct platform_device *pdev)
*/
dev->fifo_size = (dev->fifo_size / 2);
dev->b_hw = 1; /* Enable hardware fixes */
- }
+ }
/* reset ASAP, clearing any IRQs */
omap_i2c_init(dev);
@@ -856,13 +931,14 @@ omap_i2c_probe(struct platform_device *pdev)
pdev->id, dev->rev >> 4, dev->rev & 0xf, dev->speed);
omap_i2c_idle(dev);
-
adap = &dev->adapter;
i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON;
strncpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));
+ /* if BusId is 1-3 then algorithm is omap_i2c_algo */
adap->algo = &omap_i2c_algo;
+
adap->dev.parent = &pdev->dev;
/* i2c device drivers may be active on return from add_adapter() */
@@ -911,6 +987,61 @@ omap_i2c_remove(struct platform_device *pdev)
return 0;
}
+static int __init
+omap_i2c4_probe(struct platform_device *pdev)
+{
+ struct omap_i2c_dev *dev;
+ struct i2c_adapter *adap;
+ int r = 0;
+ u32 *speed = NULL;
+
+ dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL);
+ if (!dev)
+ r = -ENOMEM;
+
+ if (pdev->dev.platform_data != NULL)
+ speed = (u32 *) pdev->dev.platform_data;
+ else
+ *speed = 100; /* Defualt speed */
+
+ dev->speed = *speed;
+ dev->idle = 1;
+ dev->dev = &pdev->dev;
+
+ platform_set_drvdata(pdev, dev);
+
+ r = omap_i2c_get_clocks(dev);
+
+ adap = &dev->adapter;
+ i2c_set_adapdata(adap, dev);
+ adap->owner = THIS_MODULE;
+ adap->class = I2C_CLASS_HWMON;
+ strncpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));
+ /* BusId is 4(I2C4) then algorithm is different */
+ adap->algo = &omap_i2c4_algo;
+
+ adap->dev.parent = &pdev->dev;
+
+ /* i2c device drivers may be active on return from add_adapter() */
+ adap->nr = pdev->id;
+ r = i2c_add_numbered_adapter(adap);
+ if (r)
+ dev_err(dev->dev, "failure adding adapter\n");
+
+ return r;
+}
+
+static int
+omap_i2c4_remove(struct platform_device *pdev)
+{
+ struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
+ platform_set_drvdata(pdev, NULL);
+ i2c_del_adapter(&dev->adapter);
+ kfree(dev);
+ return 0;
+}
+
+
static struct platform_driver omap_i2c_driver = {
.probe = omap_i2c_probe,
.remove = omap_i2c_remove,
@@ -920,17 +1051,32 @@ static struct platform_driver omap_i2c_driver = {
},
};
+static struct platform_driver omap_i2c4_driver = {
+ .probe = omap_i2c4_probe,
+ .remove = omap_i2c4_remove,
+ .driver = {
+ .name = "i2c4_omap",
+ .owner = THIS_MODULE,
+ },
+};
+
+
/* I2C may be needed to bring up other drivers */
static int __init
omap_i2c_init_driver(void)
{
- return platform_driver_register(&omap_i2c_driver);
+ int ret = 0;
+ ret = platform_driver_register(&omap_i2c_driver);
+ ret = platform_driver_register(&omap_i2c4_driver);
+
+ return ret;
}
subsys_initcall(omap_i2c_init_driver);
static void __exit omap_i2c_exit_driver(void)
{
platform_driver_unregister(&omap_i2c_driver);
+ platform_driver_unregister(&omap_i2c4_driver);
}
module_exit(omap_i2c_exit_driver);
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index d61589b..5702520 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -194,6 +194,29 @@ config SENSORS_MAX6875
This driver can also be built as a module. If so, the module
will be called max6875.
+choice
+ prompt "TPS6235X driver support"
+ depends on I2C=y && PR785=y
+ default n
+ help
+ nothing.
+
+ config TPS6235X_I2C2
+ bool "TPS6235X_I2C2"
+ help
+ Say yes here if you have TPS6235x devices connected to I2C Bus2
+ on PR785 Power module. Note that while selecting this option,
+ TPS6235X_I2C4 should not be selected.
+
+ config TPS6235X_I2C4
+ bool "TPS6235X_I2C4"
+ help
+ Say yes here if you have TPS6235x devices connected to I2C Bus4
+ on PR785 Power module. Note that while selecting this option,
+ TPS6235X_I2C2 should not be selected.
+
+endchoice
+
config SENSORS_TSL2550
tristate "Taos TSL2550 ambient light sensor"
depends on EXPERIMENTAL
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 0765389..6a827e5 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -80,4 +80,11 @@ config REGULATOR_DA903X
Say y here to support the BUCKs and LDOs regulators found on
Dialog Semiconductor DA9030/DA9034 PMIC.
+config REGULATOR_TPS6235X
+ bool "TPS6235X Power regulator for OMAP3EVM"
+ depends on PR785
+ help
+ This driver supports the voltage regulators provided by TPS6235x chips.
+ The TPS62352 and TPS62353 are mounted on PR785 Power module card for
+ providing voltage regulator functions.
endif
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 0dacb18..fdc5f5b 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -12,5 +12,6 @@ obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
+obj-$(CONFIG_REGULATOR_TPS6235X)+= tps6235x-regulator.o
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 02a7744..901f402 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -30,33 +30,6 @@ static LIST_HEAD(regulator_list);
static LIST_HEAD(regulator_map_list);
/**
- * struct regulator_dev
- *
- * Voltage / Current regulator class device. One for each regulator.
- */
-struct regulator_dev {
- struct regulator_desc *desc;
- int use_count;
-
- /* lists we belong to */
- struct list_head list; /* list of all regulators */
- struct list_head slist; /* list of supplied regulators */
-
- /* lists we own */
- struct list_head consumer_list; /* consumers we supply */
- struct list_head supply_list; /* regulators we supply */
-
- struct blocking_notifier_head notifier;
- struct mutex mutex; /* consumer lock */
- struct module *owner;
- struct device dev;
- struct regulation_constraints *constraints;
- struct regulator_dev *supply; /* for tree */
-
- void *reg_data; /* regulator_dev data */
-};
-
-/**
* struct regulator_map
*
* Used to provide symbolic supply names to devices.
diff --git a/drivers/regulator/tps6235x-regulator.c b/drivers/regulator/tps6235x-regulator.c
new file mode 100644
index 0000000..8a900db
--- /dev/null
+++ b/drivers/regulator/tps6235x-regulator.c
@@ -0,0 +1,544 @@
+/*
+ * tps6235x-regulator.c -- support regulators in tps6235x family chips
+ *
+ * Copyright (C) 2008 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/regulator/consumer.h>
+
+/* Minimum and Maximum dc-dc voltage supported by the TPS6235x devices
+All voltages given in millivolts */
+#define PR785_MIN_CORE_VOLT 750
+#define PR785_MAX_CORE_VOLT 1537
+#define PR785_MIN_MPU_VOLT 750
+#define PR785_MAX_MPU_VOLT 1537
+
+/* Maximum number of bytes to be read in a single read */
+#define PR785_RETRY_COUNT 0x3
+
+/* Register bit settings */
+#define TPS6235X_EN_DCDC (0x1 << 0x7)
+#define TPS6235X_VSM_MSK (0x3F)
+#define TPS6235X_EN_SYN_MSK (0x1 << 0x5)
+#define TPS6235X_SW_VOLT_MSK (0x1 << 0x4)
+#define TPS6235X_PWR_OK_MSK (0x1 << 0x5)
+#define TPS6235X_OUT_DIS_MSK (0x1 << 0x6)
+#define TPS6235X_GO_MSK (0x1 << 0x7)
+
+/*
+ * These chips are often used in OMAP-based systems.
+ *
+ * This driver implements software-based resource control for various
+ * voltage regulators. This is usually augmented with state machine
+ * based control.
+ */
+struct tps_6235x_info {
+ unsigned int state;
+ unsigned int tps_i2c_addr;
+ struct i2c_client *client;
+ struct device *i2c_dev;
+ /* platform data holder */
+ void *pdata;
+};
+
+static struct tps_6235x_info tps_6235x_infodata[2];
+
+
+#ifndef REGULATOR_MODE_OFF
+#define REGULATOR_MODE_OFF 0
+#endif
+
+
+/* LDO control registers ... offset is from the base of its register bank.
+ * The first three registers of all power resource banks help hardware to
+ * manage the various resource groups.
+ */
+
+#define TPS6235X_REG_VSEL0 0
+#define TPS6235X_REG_VSEL1 1
+#define TPS6235X_REG_CTRL1 2
+#define TPS6235X_REG_CTRL2 3
+#define TPS6235X_REG_MAX TPS6235X_REG_CTRL2
+
+#define MODULE_NAME "tps6235x_power"
+
+/* Debug functions */
+#ifdef DEBUG
+
+#define dump_reg(client, reg, val) \
+ do { \
+ tps6235x_read_reg(client, reg, &val); \
+ dev_dbg(&(client)->dev, "Reg(0x%.2X): 0x%.2X\n", reg, val); \
+ } while (0)
+
+#endif /* #ifdef DEBUG */
+
+/* Device addresses for PR785 card */
+#define PR785_62352_CORE_ADDR 0x4A
+#define PR785_62353_MPU_ADDR 0x48
+
+/* Minimum and Maximum dc-dc voltage supported by the TPS6235x devices
+All voltages given in millivolts */
+#define PR785_MIN_CORE_VOLT 750
+#define PR785_MAX_CORE_VOLT 1537
+#define PR785_MIN_MPU_VOLT 750
+#define PR785_MAX_MPU_VOLT 1537
+
+/* Maximum number of bytes to be read in a single read */
+#define PR785_RETRY_COUNT 0x3
+
+/* Register bit settings */
+#define TPS6235X_EN_DCDC (0x1 << 0x7)
+#define TPS6235X_VSM_MSK (0x3F)
+#define TPS6235X_EN_SYN_MSK (0x1 << 0x5)
+#define TPS6235X_SW_VOLT_MSK (0x1 << 0x4)
+#define TPS6235X_PWR_OK_MSK (0x1 << 0x5)
+#define TPS6235X_OUT_DIS_MSK (0x1 << 0x6)
+#define TPS6235X_GO_MSK (0x1 << 0x7)
+
+int pr785_enbl_dcdc(unsigned char tps_mod_type, unsigned int en_flag);
+int pr785_get_dcdc_volt(unsigned char tps_mod_type, unsigned int *millivolts);
+int pr785_set_dcdc_volt(unsigned char tps_mod_type, unsigned int millivolts);
+
+static int tps6235x_dcdc_is_enabled(struct regulator_dev *dev)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+ return tps_info->state;
+}
+
+static int tps6235x_dcdc_enable(struct regulator_dev *dev)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+
+ tps_info->state = 1;
+ return pr785_enbl_dcdc(tps_info->tps_i2c_addr, 1);
+}
+
+static int tps6235x_dcdc_disable(struct regulator_dev *dev)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+
+ tps_info->state = 0;
+ return pr785_enbl_dcdc(tps_info->tps_i2c_addr, 0);
+}
+
+static int tps6235x_dcdc_get_voltage(struct regulator_dev *dev)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+ unsigned int millivolts;
+
+ pr785_get_dcdc_volt(tps_info->tps_i2c_addr, &millivolts);
+ return millivolts * 1000;
+}
+
+static int tps6235x_dcdc_set_voltage(struct regulator_dev *dev,
+ int min_uV, int max_uV)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+ unsigned int millivolts = max_uV / 1000;
+
+ return pr785_set_dcdc_volt(tps_info->tps_i2c_addr, millivolts) ;
+}
+
+
+static struct regulator_ops tps62352_dcdc_ops = {
+ .is_enabled = tps6235x_dcdc_is_enabled,
+ .get_voltage = tps6235x_dcdc_get_voltage,
+ .set_voltage = tps6235x_dcdc_set_voltage,
+};
+
+static struct regulator_ops tps62353_dcdc_ops = {
+ .is_enabled = tps6235x_dcdc_is_enabled,
+ .enable = tps6235x_dcdc_enable,
+ .disable = tps6235x_dcdc_disable,
+ .get_voltage = tps6235x_dcdc_get_voltage,
+ .set_voltage = tps6235x_dcdc_set_voltage,
+};
+
+
+static struct regulator_desc regulators[] = {
+ {
+ .name = "tps62352",
+ .id = 2,
+ .ops = &tps62352_dcdc_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+ {
+ .name = "tps62353",
+ .id = 3,
+ .ops = &tps62353_dcdc_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int tps6235xreg_probe(struct platform_device *pdev)
+{
+ struct tps_6235x_info *info;
+ struct regulator_dev *rdev = NULL;
+
+ info = &tps_6235x_infodata[(pdev->id-2)];
+
+ rdev = regulator_register(&regulators[(pdev->id-2)], &pdev->dev, info);
+ if (rdev == NULL)
+ printk(KERN_ERR "err in regulator registry = %d\n", pdev->id);
+
+ platform_set_drvdata(pdev, rdev);
+
+ return 0;
+}
+
+static int __devexit tps6235xreg_remove(struct platform_device *pdev)
+{
+ regulator_unregister(platform_get_drvdata(pdev));
+ return 0;
+}
+
+MODULE_ALIAS("platform:tps6235x_reg");
+
+static struct platform_driver tps6235xreg_driver = {
+ .probe = tps6235xreg_probe,
+ .remove = __devexit_p(tps6235xreg_remove),
+ .driver.name = "tps6235x_reg",
+ .driver.owner = THIS_MODULE,
+};
+
+static int __init tps6235xreg_init(void)
+{
+ return platform_driver_register(&tps6235xreg_driver);
+}
+late_initcall(tps6235xreg_init);
+
+static void __exit tps6235xreg_exit(void)
+{
+ platform_driver_unregister(&tps6235xreg_driver);
+}
+module_exit(tps6235xreg_exit)
+
+MODULE_DESCRIPTION("TPS6235X regulator driver");
+MODULE_LICENSE("GPL");
+
+
+/*
+ * Get client pointer for a particular device
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static struct i2c_client *tps_6235x_get_client(unsigned char tps_i2c_addr)
+{
+ if (tps_i2c_addr == PR785_62352_CORE_ADDR)
+ return tps_6235x_infodata[0].client;
+ else if (tps_i2c_addr == PR785_62353_MPU_ADDR)
+ return tps_6235x_infodata[1].client;
+ else
+ return NULL;
+}
+
+/*
+ * Read a value from a register in an tps_6235x device.
+ * The value is returned in 'val'.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int tps_6235x_read_reg(struct i2c_client *client, u8 reg, u8 *val)
+{
+ u8 data;
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ data = i2c_smbus_read_byte_data(client, reg);
+ *val = data;
+ return 0;
+}
+
+/*
+ * Write a value to a register in an tps_6235x device.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int tps_6235x_write_reg(struct i2c_client *client, u8 reg, u8 val)
+{
+ int err;
+ int retry = 0;
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ err = i2c_smbus_write_byte_data(client, reg, val);
+ if (err >= 0)
+ return 0;
+
+ dev_err(&client->dev,
+ "wrote 0x%.2x to offset 0x%.2x error %d\n", val, reg, err);
+
+ if (retry <= PR785_RETRY_COUNT) {
+ dev_info(&client->dev, "retry ... %d\n", retry);
+ retry++;
+ schedule_timeout(msecs_to_jiffies(20));
+ goto again;
+ }
+ return err;
+}
+
+
+/**
+* pwr_i2c_read - Allows the caller to read one register from TPS device
+* based on the address given. For the PR785 it reads
+* only 1 byte into a specified register
+* tps_mod_type - Enum for the device to be read
+* reg - Register to be read from(value has to be between 0-3
+* val - value read from the reg
+* Retval - 0 -> Success else non-zero
+**/
+int pwr_i2c_read(unsigned char tps_mod_type, u8 reg, u8 *val)
+{
+ struct i2c_client *client;
+
+ client = tps_6235x_get_client(tps_mod_type);
+ /* check if register is less than <= 3 Register is 0 -3 */
+ if (reg > TPS6235X_REG_MAX)
+ return -1;
+
+ return tps_6235x_read_reg(client, reg, val);
+}
+EXPORT_SYMBOL(pwr_i2c_read);
+
+/**
+* pwr_i2c_write - Allows the caller to write one register from TPS device
+* based on the address given. For the PR785 it writes
+* only 1 byte into a specified register
+* tps_mod_type - Enum for the device to be written
+* reg - Register to be written to(value has to be between 0-3
+* val - value to be written to reg
+* Retval - 0 -> Success else non-zero
+**/
+int pwr_i2c_write(unsigned char tps_mod_type, u8 reg, u8 val)
+{
+ struct i2c_client *client;
+
+ client = tps_6235x_get_client(tps_mod_type);
+
+ /* check if register is less than <= 3 Register is 0 -3 */
+ if (reg > TPS6235X_REG_MAX)
+ return -1;
+
+ return tps_6235x_write_reg(client, reg, val);
+}
+EXPORT_SYMBOL(pwr_i2c_write);
+
+
+/**
+* TPSPR785 - Specific functions
+* pr785_enbl_dcdc - Allows the caller to enable or disable the TPS6235x device
+* on the PR785 board. The voltage for PR785 is selected by
+* VSEL1 register since VSEL pin is kept high
+*
+* flag - 1 == enable 0 == disable
+* Retval - 0 -> Success else non-zero
+**/
+int pr785_enbl_dcdc(unsigned char tps_mod_type, unsigned int en_flag)
+{
+ unsigned char vsel1;
+ int ret;
+
+ ret = pwr_i2c_read(tps_mod_type, TPS6235X_REG_VSEL1, &vsel1);
+ if (ret == 0) {
+ if (en_flag)
+ vsel1 |= TPS6235X_EN_DCDC;
+ else
+ vsel1 &= ~(TPS6235X_EN_DCDC);
+ ret = pwr_i2c_write(tps_mod_type, TPS6235X_REG_VSEL1, vsel1);
+ }
+ return ret;
+}
+EXPORT_SYMBOL(pr785_enbl_dcdc);
+
+/**
+* TPSPR785 - Specific functions
+* pr785_set_dcdc_volt - Allows the caller to set a particular voltage on
+* for CORE or MPU
+*
+* voltage - voltage to be set in millivolts (75--1537)
+* Retval - 0 -> Success else non-zero
+**/
+int pr785_set_dcdc_volt(unsigned char tps_mod_type, unsigned int millivolts)
+{
+ unsigned char vsel1;
+ unsigned int volt;
+
+ /* check if the millivolts is within range */
+ if ((millivolts < PR785_MIN_CORE_VOLT) ||
+ (millivolts > PR785_MAX_CORE_VOLT))
+ return -1;
+
+ /* Output voltage set is = min_op_volt + ( VSM * 12.5mv) */
+ volt = millivolts - PR785_MIN_CORE_VOLT;
+ volt /= 25;
+ volt *= 2;
+ vsel1 = ((TPS6235X_EN_DCDC) | (volt & TPS6235X_VSM_MSK));
+ return pwr_i2c_write(tps_mod_type, TPS6235X_REG_VSEL1, vsel1);
+}
+EXPORT_SYMBOL(pr785_set_dcdc_volt);
+
+/**
+* TPSPR785 - Specific functions
+* pr785_get_dcdc_volt - Allows the caller to get the set voltage on a
+* particular TPS 6235x device on PR785 card
+*
+* voltage - voltage to be set in millivolts (75--1537)
+* Retval - 0 -> Success else non-zero
+**/
+int pr785_get_dcdc_volt(unsigned char tps_mod_type, unsigned int *millivolts)
+{
+ unsigned char vsel1;
+ unsigned int volt;
+
+ /* Read the VSEL1 register to get VSM */
+ pwr_i2c_read(tps_mod_type, TPS6235X_REG_VSEL1, &vsel1);
+ /* Output voltage set is = min_op_volt + ( VSM * 12.5mv) */
+ /* To cut out floating point operation we will multiply by 25
+ divide by 2 */
+ volt = (((vsel1 & TPS6235X_VSM_MSK) * 25) / 2) + PR785_MIN_CORE_VOLT;
+ *millivolts = volt;
+ return 0;
+}
+EXPORT_SYMBOL(pr785_get_dcdc_volt);
+
+/**
+ * tps_6235x_probe - TPS6235x driver i2c probe handler
+ *
+ * Register PR785 as an i2c client device driver
+ */
+static struct i2c_driver tps_6235x_i2c_driver;
+
+static
+int tps_6235x_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ unsigned char reg_val;
+
+ printk(KERN_INFO "tps_6235x_probe:i2c_addr = %x\n", (int)client->addr);
+
+ /* Device probed is TPS62352 CORE pwr chip if driver_data = 0
+ Device probed is TPS62353 MPU pwr chip if driver_data = 1 */
+ tps_6235x_infodata[id->driver_data].client = client;
+ tps_6235x_infodata[id->driver_data].tps_i2c_addr = client->addr;
+ tps_6235x_infodata[id->driver_data].state = 1;
+ tps_6235x_infodata[id->driver_data].i2c_dev = &client->dev;
+
+ tps_6235x_read_reg(client, TPS6235X_REG_CTRL2, &reg_val);
+ reg_val |= (TPS6235X_OUT_DIS_MSK | TPS6235X_GO_MSK);
+ tps_6235x_write_reg(client, TPS6235X_REG_CTRL2, reg_val);
+ tps_6235x_read_reg(client, TPS6235X_REG_CTRL2, &reg_val);
+
+ i2c_set_clientdata(client, &tps_6235x_infodata[id->driver_data]);
+
+ if (reg_val & TPS6235X_PWR_OK_MSK)
+ printk(KERN_INFO "Power is OK %x\n", reg_val);
+ else
+ printk(KERN_INFO "Power not within range = %x\n", reg_val);
+ return 0;
+}
+
+/**
+ * tps_6235x_remove - TPS6235x driver i2c remove handler
+ *
+ * UnregisterPR785 as an i2c client device driver
+ */
+static int __exit tps_6235x_remove(struct i2c_client *client)
+{
+#ifdef DEBUG
+ printk(KERN_INFO "tps_6235x_remove invoked\n");
+#endif
+
+ if (!client->adapter)
+ return -ENODEV; /* our client isn't attached */
+
+ i2c_set_clientdata(client, NULL);
+
+ return 0;
+}
+
+
+static const struct i2c_device_id tps_6235x_id[] = {
+ { "tps62352", 0},
+ { "tps62353", 1},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, tps_6235x_id);
+
+static struct i2c_driver tps_6235x_i2c_driver = {
+ .driver = {
+ .name = MODULE_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = tps_6235x_probe,
+ .remove = __exit_p(tps_6235x_remove),
+ .id_table = tps_6235x_id,
+};
+
+/**
+ * tps_6235x_init
+ *
+ * Module init function
+ */
+static int __init tps_6235x_init(void)
+{
+ int err;
+
+#ifdef DEBUG
+ printk(KERN_INFO "tps_6235x_init invoked\n");
+#endif
+
+ err = i2c_add_driver(&tps_6235x_i2c_driver);
+ if (err) {
+ printk(KERN_ERR "Failed to register " MODULE_NAME ".\n");
+ return err;
+ } else
+ printk(KERN_INFO "I2c driver registered\n");
+
+ return 0;
+}
+
+/**
+ * tps_6235x_cleanup
+ *
+ * Module exit function
+ */
+static void __exit tps_6235x_cleanup(void)
+{
+#ifdef DEBUG
+ printk(KERN_INFO "tps_6235x_cleanup invoked\n");
+#endif
+ i2c_del_driver(&tps_6235x_i2c_driver);
+}
+
+late_initcall(tps_6235x_init);
+module_exit(tps_6235x_cleanup);
+
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("TPS6235x based PR785 linux driver");
+MODULE_LICENSE("GPL");
+
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index e37d805..9107344 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -18,9 +18,30 @@
#include <linux/device.h>
#include <linux/regulator/consumer.h>
-struct regulator_dev;
struct regulator_init_data;
+struct regulator_dev {
+ struct regulator_desc *desc;
+ int use_count;
+
+ /* lists we belong to */
+ struct list_head list; /* list of all regulators */
+ struct list_head slist; /* list of supplied regulators */
+
+ /* lists we own */
+ struct list_head consumer_list; /* consumers we supply */
+ struct list_head supply_list; /* regulators we supply */
+
+ struct blocking_notifier_head notifier;
+ struct mutex mutex; /* consumer lock */
+ struct module *owner;
+ struct device dev;
+ struct regulation_constraints *constraints;
+ struct regulator_dev *supply; /* for tree */
+
+ void *reg_data; /* regulator_dev data */
+};
+
/**
* struct regulator_ops - regulator operations.
*
--
1.5.6
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
More majordomo info at http://vger.kernel.org/majordomo-info.html
--
balbi

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Felipe Balbi
2008-12-04 11:41:40 UTC
Permalink
Post by Pillai, Manikandan
Hi,
Pls find comments inlined.
regards
-----Original Message-----
Sent: Thursday, December 04, 2008 4:49 PM
Subject: Re: [PATCH 2/2] Putting TPS6235x into the power regulator framework
Post by y***@india.ti.com
This patch moves the TPS6235x drivers from the drivers/i2c to drivers/
regulator to put the TPS6235x drivers under the power regulator framework
suffix core_pwr and mpu_pwr has been removed
I2C bus speeds replaced with numbers again
Camel case has been removed
TPS moved into regulator framework and drivers/i2c/chips left untouched.
Not clear on how to implement runtime check for PR785 and would require some
inputs on implementing the same.
This patch should be broken into smaller pieces.
[Pillai, Manikandan] OK
The tps driver should come separated, drivers/regulator/core.c should go
to the maintainer in a separate patch, i2c-omap.c adding the i2c4
support, should be in a separate patch and Ccing Ben Dooks and Jean
Delvare.
[Pillai, Manikandan] In core.c, I am just moving the definition of a struct to
the header file.
yes and you should let the maintainer of that driver know about it and
see if he agrees with that. Otherwise we'll be adding an omap fork of an
upstream driver.
Post by Pillai, Manikandan
heh, i thought bus4 wasn't sw controllable :-s
[Pillai, Manikandan] Bus 4 can be used to write from master. It cannot be used to read.
good to know ;-)
Post by Pillai, Manikandan
this is not the correct place for it as only one board has this driver.
Move it to the proper board-file.
[Pillai, Manikandan] I will move it to board-omap3evm.c
good.
Post by Pillai, Manikandan
supply should be Vdd, or Vbus or something more useful, not the chip's
name.
[Pillai, Manikandan] Shall make it vdd1 and vdd2 and map it exactly as in
OMAP spec.
Most likely yeah, then it's also easy to search in the docs for
references ;-)
--
balbi
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Mark Brown
2008-12-04 12:04:18 UTC
Permalink
Post by y***@india.ti.com
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &tps6235x_consumers[0],
...
Post by y***@india.ti.com
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &tps6235x_consumers[1],
This code will work but flags up alarm bells when doing review - it
would be clearer to declare two separate variables, which is also less
error prone if someone takes your code and uses it as a template for
another board.
Post by y***@india.ti.com
+config REGULATOR_TPS6235X
+ bool "TPS6235X Power regulator for OMAP3EVM"
+ depends on PR785
+ help
+ This driver supports the voltage regulators provided by TPS6235x chips.
+ The TPS62352 and TPS62353 are mounted on PR785 Power module card for
+ providing voltage regulator functions.
This should probably be two drivers: a driver for the TPS6235x and a
driver for the power module card, otherwise systems that use the chip on
a different board won't be able to do so. Looking at the code it seems
you've got something fairly close to this structure already, it just
needs exposing.
Post by y***@india.ti.com
index 02a7744..901f402 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -30,33 +30,6 @@ static LIST_HEAD(regulator_list);
static LIST_HEAD(regulator_map_list);
/**
- * struct regulator_dev
- *
- * Voltage / Current regulator class device. One for each regulator.
- */
-struct regulator_dev {
- struct regulator_desc *desc;
- int use_count;
This is... interesting? I think all you're doing is looking inside to
get the driver data rather than using regulator_get_drvdata() - is there
anything else?
Post by y***@india.ti.com
new file mode 100644
index 0000000..8a900db
--- /dev/null
+++ b/drivers/regulator/tps6235x-regulator.c
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/regulator/consumer.h>
Do you need the consumer header here?
Post by y***@india.ti.com
+
+#define MODULE_NAME "tps6235x_power"
Really?
Post by y***@india.ti.com
+/* Debug functions */
+#ifdef DEBUG
+
+#define dump_reg(client, reg, val) \
+ do { \
+ tps6235x_read_reg(client, reg, &val); \
+ dev_dbg(&(client)->dev, "Reg(0x%.2X): 0x%.2X\n", reg, val); \
+ } while (0)
+
+#endif /* #ifdef DEBUG */
static inline?
Post by y***@india.ti.com
+/* Maximum number of bytes to be read in a single read */
+#define PR785_RETRY_COUNT 0x3
The name and comment don't seem to match up very well...
Post by y***@india.ti.com
+static int tps6235x_dcdc_is_enabled(struct regulator_dev *dev)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
Should use regulator_get_drvdata() for this.
Post by y***@india.ti.com
+ return tps_info->state;
+}
+static int tps6235x_dcdc_set_voltage(struct regulator_dev *dev,
+ int min_uV, int max_uV)
+{
+ struct tps_6235x_info *tps_info =
+ (struct tps_6235x_info *)dev->reg_data;
+ unsigned int millivolts = max_uV / 1000;
+
+ return pr785_set_dcdc_volt(tps_info->tps_i2c_addr, millivolts) ;
+}
Normally you'd want to go for the lowest voltage you can in the range
rather than the highest voltage. A driver doing voltage scaling for
power saving would be likely to call set_voltage() with a range from the
minimum that could currently be used to the maximum rated for the chip
since it's only trying to save power, it doesn't specifically *need* the
lower voltage. This allows the driver to run on systems where there are
additional constraints which prevent the use of the lowest voltages.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
David Brownell
2008-12-05 21:38:45 UTC
Permalink
I second the comment on splitting this patch up into
its constituent chunks. It'll be practical to review
each of them properly at that point.

Like ... it seems wrong to teach plat-omap/devices.c
about EVM-specific stuff; it should stay generic.

And those EVM-specific bits are done wrong too; those
regulators are I2C devices, not platform devices!
Plus, their constraints should be board-specific, not
generic. Move all that into the omap3evm board code.

You still didn't remove the drivers/i2c/chips stuff.
Move the *ENTIRE* driver to drivers/regulator, and
get rid of all the platform_device stuff.

Good to see this driver start moving into its proper
home, though. :)
Post by y***@india.ti.com
Not clear on how to implement runtime check for PR785 and would require some
inputs on implementing the same.
The TPS driver should not know or care about the PR785 card;
it should just respond to the various requests. If there's
any knowledge of PR785 in drivers/anything/* you should treat
that as a bug (and fix it before merge). Since the chips are
pretty much the same other than some bit interpretations, just
use the driver_data in the i2c_device_id to describe whatever
differences the driver needs to know about.

With respect to runtime checking, first make sure the
OMAP3 EVM init code is able to cleanly choose between the
two power card options. Once that's done you can try
turning that into a runtime check.

- Dave
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Dmitry Kasatkin
2010-11-10 17:26:51 UTC
Permalink
Dmitry Kasatkin (5):
crypto: omap-aes: change in prevention of OCP bus error
omap-aes: DMA initialization fixes for OMAP off mode
omap-aes: redundant locking is removed
omap-aes: error handling implementation improved
omap-aes: unnecessary code removed

drivers/crypto/omap-aes.c | 269 ++++++++++++++++++++++++---------------------
1 files changed, 143 insertions(+), 126 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Dmitry Kasatkin
2010-11-10 17:26:52 UTC
Permalink
Suggested to use udelay() instead of nop as on the higher
core frequencies it might not be enough time.

Signed-off-by: Dmitry Kasatkin <***@nokia.com>
---
drivers/crypto/omap-aes.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 799ca51..9d65611 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -26,6 +26,7 @@
#include <linux/io.h>
#include <linux/crypto.h>
#include <linux/interrupt.h>
+#include <linux/delay.h>
#include <crypto/scatterwalk.h>
#include <crypto/aes.h>

@@ -187,11 +188,12 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd)
omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_SOFTRESET,
AES_REG_MASK_SOFTRESET);
/*
- * prevent OCP bus error (SRESP) in case an access to the module
- * is performed while the module is coming out of soft reset
+ * prevent OCP bus error (SRESP) on OMAP3630 in case an access
+ * to the module is performed while the module is
+ * coming out of soft reset
*/
- __asm__ __volatile__("nop");
- __asm__ __volatile__("nop");
+ if (cpu_is_omap3630())
+ udelay(1);

err = omap_aes_wait(dd, AES_REG_SYSSTATUS,
AES_REG_SYSSTATUS_RESETDONE);
--
1.7.0.4
Tony Lindgren
2010-11-16 17:13:55 UTC
Permalink
Hi,
Post by Dmitry Kasatkin
Suggested to use udelay() instead of nop as on the higher
core frequencies it might not be enough time.
---
drivers/crypto/omap-aes.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 799ca51..9d65611 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -26,6 +26,7 @@
#include <linux/io.h>
#include <linux/crypto.h>
#include <linux/interrupt.h>
+#include <linux/delay.h>
#include <crypto/scatterwalk.h>
#include <crypto/aes.h>
@@ -187,11 +188,12 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd)
omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_SOFTRESET,
AES_REG_MASK_SOFTRESET);
/*
- * prevent OCP bus error (SRESP) in case an access to the module
- * is performed while the module is coming out of soft reset
+ * prevent OCP bus error (SRESP) on OMAP3630 in case an access
+ * to the module is performed while the module is
+ * coming out of soft reset
*/
- __asm__ __volatile__("nop");
- __asm__ __volatile__("nop");
+ if (cpu_is_omap3630())
+ udelay(1);
err = omap_aes_wait(dd, AES_REG_SYSSTATUS,
AES_REG_SYSSTATUS_RESETDONE);
Please don't add more cpu_is_omapxxxx tests into drivers, those
will be limited to arch/arm/*omap*/ platform init code soonish.
The drivers should be generic.

Instead, check the crypto hardware version during init. If that
does not work, pass u32 flags in the platform data and define
OMAP_AES_SOFT_RESET_ERROR bit.

Regards,

Tony
Dmitry Kasatkin
2010-11-10 17:26:54 UTC
Permalink
Submitting request involved double locking for enqueuing and
dequeuing. Now it is done under the same lock.

FLAGS_BUSY is now handled under the same lock.

Signed-off-by: Dmitry Kasatkin <***@nokia.com>
---
drivers/crypto/omap-aes.c | 68 ++++++++++++++++++++------------------------
1 files changed, 31 insertions(+), 37 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 04cab70..a4d0ef4 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -79,7 +79,7 @@
#define FLAGS_NEW_IV BIT(5)
#define FLAGS_INIT BIT(6)
#define FLAGS_FAST BIT(7)
-#define FLAGS_BUSY 8
+#define FLAGS_BUSY BIT(8)

struct omap_aes_ctx {
struct omap_aes_dev *dd;
@@ -180,9 +180,10 @@ static int omap_aes_wait(struct omap_aes_dev *dd, u32 offset, u32 bit)

static int omap_aes_hw_init(struct omap_aes_dev *dd)
{
- int err = 0;
+ int err;

clk_enable(dd->iclk);
+
if (!(dd->flags & FLAGS_INIT)) {
/* is it necessary to reset before every operation? */
omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_SOFTRESET,
@@ -195,18 +196,14 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd)
if (cpu_is_omap3630())
udelay(1);

- err = omap_aes_wait(dd, AES_REG_SYSSTATUS,
- AES_REG_SYSSTATUS_RESETDONE);
- if (!err)
- dd->flags |= FLAGS_INIT;
+ if (omap_aes_wait(dd, AES_REG_SYSSTATUS,
+ AES_REG_SYSSTATUS_RESETDONE)) {
+ clk_disable(dd->iclk);
+ return -ETIMEDOUT;
+ dd->flags |= FLAGS_INIT;
}

- return err;
-}
-
-static void omap_aes_hw_cleanup(struct omap_aes_dev *dd)
-{
- clk_disable(dd->iclk);
+ return 0;
}

static void omap_aes_write_ctrl(struct omap_aes_dev *dd)
@@ -540,6 +537,8 @@ static void omap_aes_finish_req(struct omap_aes_dev *dd, int err)

pr_debug("err: %d\n", err);

+ dd->flags &= ~FLAGS_BUSY;
+
ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(dd->req));

if (!dd->total)
@@ -555,7 +554,7 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)

omap_aes_write_mask(dd, AES_REG_MASK, 0, AES_REG_MASK_START);

- omap_aes_hw_cleanup(dd);
+ clk_disable(dd->iclk);

omap_stop_dma(dd->dma_lch_in);
omap_stop_dma(dd->dma_lch_out);
@@ -582,22 +581,27 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)
return err;
}

-static int omap_aes_handle_req(struct omap_aes_dev *dd)
+static int omap_aes_handle_req(struct omap_aes_dev *dd,
+ struct ablkcipher_request *req)
{
struct crypto_async_request *async_req, *backlog;
struct omap_aes_ctx *ctx;
struct omap_aes_reqctx *rctx;
- struct ablkcipher_request *req;
unsigned long flags;
-
- if (dd->total)
- goto start;
+ int err;

spin_lock_irqsave(&dd->lock, flags);
- backlog = crypto_get_backlog(&dd->queue);
+ if (req)
+ err = ablkcipher_enqueue_request(&dd->queue, req);
+ if (dd->flags & FLAGS_BUSY) {
+ spin_unlock_irqrestore(&dd->lock, flags);
+ return err;
+ }
async_req = crypto_dequeue_request(&dd->queue);
- if (!async_req)
- clear_bit(FLAGS_BUSY, &dd->flags);
+ if (async_req) {
+ dd->flags |= FLAGS_BUSY;
+ backlog = crypto_get_backlog(&dd->queue);
+ }
spin_unlock_irqrestore(&dd->lock, flags);

if (!async_req)
@@ -639,20 +643,21 @@ static int omap_aes_handle_req(struct omap_aes_dev *dd)
if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE))
pr_err("request size is not exact amount of AES blocks\n");

-start:
return omap_aes_crypt_dma_start(dd);
}

static void omap_aes_task(unsigned long data)
{
struct omap_aes_dev *dd = (struct omap_aes_dev *)data;
- int err;

pr_debug("enter\n");

- err = omap_aes_crypt_dma_stop(dd);
+ omap_aes_crypt_dma_stop(dd);

- err = omap_aes_handle_req(dd);
+ if (dd->total)
+ omap_aes_crypt_dma_start(dd);
+ else
+ omap_aes_handle_req(dd, NULL);

pr_debug("exit\n");
}
@@ -663,8 +668,6 @@ static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode)
crypto_ablkcipher_reqtfm(req));
struct omap_aes_reqctx *rctx = ablkcipher_request_ctx(req);
struct omap_aes_dev *dd;
- unsigned long flags;
- int err;

pr_debug("nbytes: %d, enc: %d, cbc: %d\n", req->nbytes,
!!(mode & FLAGS_ENCRYPT),
@@ -676,16 +679,7 @@ static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode)

rctx->mode = mode;

- spin_lock_irqsave(&dd->lock, flags);
- err = ablkcipher_enqueue_request(&dd->queue, req);
- spin_unlock_irqrestore(&dd->lock, flags);
-
- if (!test_and_set_bit(FLAGS_BUSY, &dd->flags))
- omap_aes_handle_req(dd);
-
- pr_debug("exit\n");
-
- return err;
+ return omap_aes_handle_req(dd, req);
}

/* ********************** ALG API ************************************ */
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Dmitry Kasatkin
2010-11-10 17:26:53 UTC
Permalink
DMA parameters for constant data were initialized during driver probe().
It seems that those settings sometimes are lost when devices goes to off mode.
This patch makes DMA initialization just before use.
It solves off mode problems.

Signed-off-by: Dmitry Kasatkin <***@nokia.com>
---
drivers/crypto/omap-aes.c | 30 +++++++++++++++---------------
1 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 9d65611..04cab70 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -99,7 +99,7 @@ struct omap_aes_reqctx {
struct omap_aes_dev {
struct list_head list;
unsigned long phys_base;
- void __iomem *io_base;
+ void __iomem *io_base;
struct clk *iclk;
struct omap_aes_ctx *ctx;
struct device *dev;
@@ -341,18 +341,6 @@ static int omap_aes_dma_init(struct omap_aes_dev *dd)
goto err_dma_out;
}

- omap_set_dma_dest_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_CONSTANT,
- dd->phys_base + AES_REG_DATA, 0, 4);
-
- omap_set_dma_dest_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4);
- omap_set_dma_src_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4);
-
- omap_set_dma_src_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_CONSTANT,
- dd->phys_base + AES_REG_DATA, 0, 4);
-
- omap_set_dma_src_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4);
- omap_set_dma_dest_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4);
-
return 0;

err_dma_out:
@@ -445,6 +433,12 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
len32 = DIV_ROUND_UP(length, sizeof(u32));

/* IN */
+ omap_set_dma_dest_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_CONSTANT,
+ dd->phys_base + AES_REG_DATA, 0, 4);
+
+ omap_set_dma_dest_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4);
+ omap_set_dma_src_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4);
+
omap_set_dma_transfer_params(dd->dma_lch_in, OMAP_DMA_DATA_TYPE_S32,
len32, 1, OMAP_DMA_SYNC_PACKET, dd->dma_in,
OMAP_DMA_DST_SYNC);
@@ -453,6 +447,12 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
dma_addr_in, 0, 0);

/* OUT */
+ omap_set_dma_src_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_CONSTANT,
+ dd->phys_base + AES_REG_DATA, 0, 4);
+
+ omap_set_dma_src_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4);
+ omap_set_dma_dest_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4);
+
omap_set_dma_transfer_params(dd->dma_lch_out, OMAP_DMA_DATA_TYPE_S32,
len32, 1, OMAP_DMA_SYNC_PACKET,
dd->dma_out, OMAP_DMA_SRC_SYNC);
@@ -752,7 +752,7 @@ static struct crypto_alg algs[] = {
.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
.cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_aes_ctx),
- .cra_alignmask = 0,
+ .cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
.cra_init = omap_aes_cra_init,
@@ -772,7 +772,7 @@ static struct crypto_alg algs[] = {
.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
.cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_aes_ctx),
- .cra_alignmask = 0,
+ .cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
.cra_init = omap_aes_cra_init,
--
1.7.0.4
Felipe Balbi
2010-11-10 17:48:20 UTC
Permalink
Hi,
Post by Dmitry Kasatkin
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 9d65611..04cab70 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -99,7 +99,7 @@ struct omap_aes_reqctx {
struct omap_aes_dev {
struct list_head list;
unsigned long phys_base;
- void __iomem *io_base;
+ void __iomem *io_base;
struct clk *iclk;
struct omap_aes_ctx *ctx;
struct device *dev;
this hunk is not part of this patch.
Post by Dmitry Kasatkin
@@ -752,7 +752,7 @@ static struct crypto_alg algs[] = {
.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
.cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_aes_ctx),
- .cra_alignmask = 0,
+ .cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
.cra_init = omap_aes_cra_init,
not part of this patch.
Post by Dmitry Kasatkin
@@ -772,7 +772,7 @@ static struct crypto_alg algs[] = {
.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
.cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct omap_aes_ctx),
- .cra_alignmask = 0,
+ .cra_alignmask = 0,
.cra_type = &crypto_ablkcipher_type,
.cra_module = THIS_MODULE,
.cra_init = omap_aes_cra_init,
not part of this patch
--
balbi

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Dmitry Kasatkin
2010-11-10 17:26:55 UTC
Permalink
Previous version had not error handling.
Request could remain uncompleted.

Also in the case of DMA error, FLAGS_INIT is unset
and accelerator will be initialized again.

Buffer size allignment is checked.

Signed-off-by: Dmitry Kasatkin <***@nokia.com>
---
drivers/crypto/omap-aes.c | 135 +++++++++++++++++++++++++++++++--------------
1 files changed, 94 insertions(+), 41 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index a4d0ef4..704c9d1 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -104,14 +104,16 @@ struct omap_aes_dev {
struct omap_aes_ctx *ctx;
struct device *dev;
unsigned long flags;
+ int err;

u32 *iv;
u32 ctrl;

- spinlock_t lock;
- struct crypto_queue queue;
+ spinlock_t lock;
+ struct crypto_queue queue;

- struct tasklet_struct task;
+ struct tasklet_struct done_task;
+ struct tasklet_struct queue_task;

struct ablkcipher_request *req;
size_t total;
@@ -180,8 +182,6 @@ static int omap_aes_wait(struct omap_aes_dev *dd, u32 offset, u32 bit)

static int omap_aes_hw_init(struct omap_aes_dev *dd)
{
- int err;
-
clk_enable(dd->iclk);

if (!(dd->flags & FLAGS_INIT)) {
@@ -200,25 +200,32 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd)
AES_REG_SYSSTATUS_RESETDONE)) {
clk_disable(dd->iclk);
return -ETIMEDOUT;
+ }
dd->flags |= FLAGS_INIT;
+ dd->err = 0;
}

return 0;
}

-static void omap_aes_write_ctrl(struct omap_aes_dev *dd)
+static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
{
unsigned int key32;
- int i;
+ int i, err, init = dd->flags & FLAGS_INIT;
u32 val, mask;

+ err = omap_aes_hw_init(dd);
+ if (err)
+ return err;
+
val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3);
if (dd->flags & FLAGS_CBC)
val |= AES_REG_CTRL_CBC;
if (dd->flags & FLAGS_ENCRYPT)
val |= AES_REG_CTRL_DIRECTION;

- if (dd->ctrl == val && !(dd->flags & FLAGS_NEW_IV) &&
+ /* check if hw state & mode have not changed */
+ if (init && dd->ctrl == val && !(dd->flags & FLAGS_NEW_IV) &&
!(dd->ctx->flags & FLAGS_NEW_KEY))
goto out;

@@ -260,6 +267,8 @@ out:
/* start DMA or disable idle mode */
omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START,
AES_REG_MASK_START);
+
+ return 0;
}

static struct omap_aes_dev *omap_aes_find_dev(struct omap_aes_ctx *ctx)
@@ -287,8 +296,16 @@ static void omap_aes_dma_callback(int lch, u16 ch_status, void *data)
{
struct omap_aes_dev *dd = data;

- if (lch == dd->dma_lch_out)
- tasklet_schedule(&dd->task);
+ if (ch_status != OMAP_DMA_BLOCK_IRQ) {
+ pr_err("omap-aes DMA error status: 0x%hx\n", ch_status);
+ dd->err = -EIO;
+ dd->flags &= ~FLAGS_INIT; /* request to re-initialize */
+ } else if (lch == dd->dma_lch_in) {
+ return;
+ }
+
+ /* dma_lch_out - completed */
+ tasklet_schedule(&dd->done_task);
}

static int omap_aes_dma_init(struct omap_aes_dev *dd)
@@ -393,6 +410,11 @@ static int sg_copy(struct scatterlist **sg, size_t *offset, void *buf,
if (!count)
return off;

+ /*
+ * buflen and total are AES_BLOCK_SIZE size aligned,
+ * so count should be also aligned
+ */
+
sg_copy_buf(buf + off, *sg, *offset, count, out);

off += count;
@@ -418,6 +440,7 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
struct omap_aes_ctx *ctx = crypto_tfm_ctx(tfm);
struct omap_aes_dev *dd = ctx->dd;
int len32;
+ int err;

pr_debug("len: %d\n", length);

@@ -457,11 +480,13 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in,
omap_set_dma_dest_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_POST_INC,
dma_addr_out, 0, 0);

+ err = omap_aes_write_ctrl(dd);
+ if (err)
+ return err;
+
omap_start_dma(dd->dma_lch_in);
omap_start_dma(dd->dma_lch_out);

- omap_aes_write_ctrl(dd);
-
return 0;
}

@@ -487,8 +512,10 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)
count = min(dd->total, sg_dma_len(dd->in_sg));
count = min(count, sg_dma_len(dd->out_sg));

- if (count != dd->total)
+ if (count != dd->total) {
+ pr_err("request length != buffer length\n");
return -EINVAL;
+ }

pr_debug("fast\n");

@@ -524,25 +551,28 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd)

dd->total -= count;

- err = omap_aes_hw_init(dd);
-
err = omap_aes_crypt_dma(tfm, addr_in, addr_out, count);
+ if (err) {
+ dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
+ dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE);
+ }

return err;
}

static void omap_aes_finish_req(struct omap_aes_dev *dd, int err)
{
+ struct ablkcipher_request *req = dd->req;
struct omap_aes_ctx *ctx;

pr_debug("err: %d\n", err);

dd->flags &= ~FLAGS_BUSY;

- ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(dd->req));
+ ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req));

- if (!dd->total)
- dd->req->base.complete(&dd->req->base, err);
+ if (req->base.complete)
+ req->base.complete(&req->base, err);
}

static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)
@@ -554,11 +584,11 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)

omap_aes_write_mask(dd, AES_REG_MASK, 0, AES_REG_MASK_START);

- clk_disable(dd->iclk);
-
omap_stop_dma(dd->dma_lch_in);
omap_stop_dma(dd->dma_lch_out);

+ clk_disable(dd->iclk);
+
if (dd->flags & FLAGS_FAST) {
dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE);
dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE);
@@ -575,27 +605,24 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)
}
}

- if (err || !dd->total)
- omap_aes_finish_req(dd, err);
-
return err;
}

-static int omap_aes_handle_req(struct omap_aes_dev *dd,
+static int omap_aes_handle_queue(struct omap_aes_dev *dd,
struct ablkcipher_request *req)
{
struct crypto_async_request *async_req, *backlog;
struct omap_aes_ctx *ctx;
struct omap_aes_reqctx *rctx;
unsigned long flags;
- int err;
+ int err, ret = 0;

spin_lock_irqsave(&dd->lock, flags);
if (req)
- err = ablkcipher_enqueue_request(&dd->queue, req);
+ ret = ablkcipher_enqueue_request(&dd->queue, req);
if (dd->flags & FLAGS_BUSY) {
spin_unlock_irqrestore(&dd->lock, flags);
- return err;
+ return ret;
}
async_req = crypto_dequeue_request(&dd->queue);
if (async_req) {
@@ -605,7 +632,7 @@ static int omap_aes_handle_req(struct omap_aes_dev *dd,
spin_unlock_irqrestore(&dd->lock, flags);

if (!async_req)
- return 0;
+ return ret;

if (backlog)
backlog->complete(backlog, -EINPROGRESS);
@@ -640,28 +667,46 @@ static int omap_aes_handle_req(struct omap_aes_dev *dd,
ctx->flags |= FLAGS_NEW_KEY;
}

- if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE))
- pr_err("request size is not exact amount of AES blocks\n");
+ err = omap_aes_crypt_dma_start(dd);
+ if (err) {
+ /* aes_task will not finish it, so do it here */
+ omap_aes_finish_req(dd, err);
+ tasklet_schedule(&dd->queue_task);
+ }

- return omap_aes_crypt_dma_start(dd);
+ return ret; /* return ret, which is enqueue return value */
}

-static void omap_aes_task(unsigned long data)
+static void omap_aes_done_task(unsigned long data)
{
struct omap_aes_dev *dd = (struct omap_aes_dev *)data;
+ int err;

pr_debug("enter\n");

- omap_aes_crypt_dma_stop(dd);
+ err = omap_aes_crypt_dma_stop(dd);

- if (dd->total)
- omap_aes_crypt_dma_start(dd);
- else
- omap_aes_handle_req(dd, NULL);
+ err = dd->err ? : err;
+
+ if (dd->total && !err) {
+ err = omap_aes_crypt_dma_start(dd);
+ if (!err)
+ return; /* DMA started. Not fininishing. */
+ }
+
+ omap_aes_finish_req(dd, err);
+ omap_aes_handle_queue(dd, NULL);

pr_debug("exit\n");
}

+static void omap_aes_queue_task(unsigned long data)
+{
+ struct omap_aes_dev *dd = (struct omap_aes_dev *)data;
+
+ omap_aes_handle_queue(dd, NULL);
+}
+
static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode)
{
struct omap_aes_ctx *ctx = crypto_ablkcipher_ctx(
@@ -673,13 +718,18 @@ static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode)
!!(mode & FLAGS_ENCRYPT),
!!(mode & FLAGS_CBC));

+ if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) {
+ pr_err("request size is not exact amount of AES blocks\n");
+ return -EINVAL;
+ }
+
dd = omap_aes_find_dev(ctx);
if (!dd)
return -ENODEV;

rctx->mode = mode;

- return omap_aes_handle_req(dd, req);
+ return omap_aes_handle_queue(dd, req);
}

/* ********************** ALG API ************************************ */
@@ -845,7 +895,8 @@ static int omap_aes_probe(struct platform_device *pdev)
(reg & AES_REG_REV_MAJOR) >> 4, reg & AES_REG_REV_MINOR);
clk_disable(dd->iclk);

- tasklet_init(&dd->task, omap_aes_task, (unsigned long)dd);
+ tasklet_init(&dd->done_task, omap_aes_done_task, (unsigned long)dd);
+ tasklet_init(&dd->queue_task, omap_aes_queue_task, (unsigned long)dd);

err = omap_aes_dma_init(dd);
if (err)
@@ -872,7 +923,8 @@ err_algs:
crypto_unregister_alg(&algs[j]);
omap_aes_dma_cleanup(dd);
err_dma:
- tasklet_kill(&dd->task);
+ tasklet_kill(&dd->done_task);
+ tasklet_kill(&dd->queue_task);
iounmap(dd->io_base);
err_io:
clk_put(dd->iclk);
@@ -899,7 +951,8 @@ static int omap_aes_remove(struct platform_device *pdev)
for (i = 0; i < ARRAY_SIZE(algs); i++)
crypto_unregister_alg(&algs[i]);

- tasklet_kill(&dd->task);
+ tasklet_kill(&dd->done_task);
+ tasklet_kill(&dd->queue_task);
omap_aes_dma_cleanup(dd);
iounmap(dd->io_base);
clk_put(dd->iclk);
--
1.7.0.4
Dmitry Kasatkin
2010-11-10 17:26:56 UTC
Permalink
Key and IV should always be set before AES operation.
So no need to check if it has changed or not.

Signed-off-by: Dmitry Kasatkin <***@nokia.com>
---
drivers/crypto/omap-aes.c | 64 +++++++++++---------------------------------
1 files changed, 16 insertions(+), 48 deletions(-)

diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 704c9d1..072f221 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -75,11 +75,9 @@
#define FLAGS_CBC BIT(1)
#define FLAGS_GIV BIT(2)

-#define FLAGS_NEW_KEY BIT(4)
-#define FLAGS_NEW_IV BIT(5)
-#define FLAGS_INIT BIT(6)
-#define FLAGS_FAST BIT(7)
-#define FLAGS_BUSY BIT(8)
+#define FLAGS_INIT BIT(4)
+#define FLAGS_FAST BIT(5)
+#define FLAGS_BUSY BIT(6)

struct omap_aes_ctx {
struct omap_aes_dev *dd;
@@ -106,9 +104,6 @@ struct omap_aes_dev {
unsigned long flags;
int err;

- u32 *iv;
- u32 ctrl;
-
spinlock_t lock;
struct crypto_queue queue;

@@ -211,28 +206,13 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd)
static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
{
unsigned int key32;
- int i, err, init = dd->flags & FLAGS_INIT;
+ int i, err;
u32 val, mask;

err = omap_aes_hw_init(dd);
if (err)
return err;

- val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3);
- if (dd->flags & FLAGS_CBC)
- val |= AES_REG_CTRL_CBC;
- if (dd->flags & FLAGS_ENCRYPT)
- val |= AES_REG_CTRL_DIRECTION;
-
- /* check if hw state & mode have not changed */
- if (init && dd->ctrl == val && !(dd->flags & FLAGS_NEW_IV) &&
- !(dd->ctx->flags & FLAGS_NEW_KEY))
- goto out;
-
- /* only need to write control registers for new settings */
-
- dd->ctrl = val;
-
val = 0;
if (dd->dma_lch_out >= 0)
val |= AES_REG_MASK_DMA_OUT_EN;
@@ -243,27 +223,28 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)

omap_aes_write_mask(dd, AES_REG_MASK, val, mask);

- pr_debug("Set key\n");
key32 = dd->ctx->keylen / sizeof(u32);
- /* set a key */
+
+ /* it seems a key should always be set even if it has not changed */
for (i = 0; i < key32; i++) {
omap_aes_write(dd, AES_REG_KEY(i),
__le32_to_cpu(dd->ctx->key[i]));
}
- dd->ctx->flags &= ~FLAGS_NEW_KEY;

- if (dd->flags & FLAGS_NEW_IV) {
- pr_debug("Set IV\n");
- omap_aes_write_n(dd, AES_REG_IV(0), dd->iv, 4);
- dd->flags &= ~FLAGS_NEW_IV;
- }
+ if ((dd->flags & FLAGS_CBC) && dd->req->info)
+ omap_aes_write_n(dd, AES_REG_IV(0), dd->req->info, 4);
+
+ val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3);
+ if (dd->flags & FLAGS_CBC)
+ val |= AES_REG_CTRL_CBC;
+ if (dd->flags & FLAGS_ENCRYPT)
+ val |= AES_REG_CTRL_DIRECTION;

mask = AES_REG_CTRL_CBC | AES_REG_CTRL_DIRECTION |
AES_REG_CTRL_KEY_SIZE;

- omap_aes_write_mask(dd, AES_REG_CTRL, dd->ctrl, mask);
+ omap_aes_write_mask(dd, AES_REG_CTRL, val, mask);

-out:
/* start DMA or disable idle mode */
omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START,
AES_REG_MASK_START);
@@ -639,8 +620,6 @@ static int omap_aes_handle_queue(struct omap_aes_dev *dd,

req = ablkcipher_request_cast(async_req);

- pr_debug("get new req\n");
-
/* assign new request to device */
dd->req = req;
dd->total = req->nbytes;
@@ -654,18 +633,8 @@ static int omap_aes_handle_queue(struct omap_aes_dev *dd,
rctx->mode &= FLAGS_MODE_MASK;
dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode;

- dd->iv = req->info;
- if ((dd->flags & FLAGS_CBC) && dd->iv)
- dd->flags |= FLAGS_NEW_IV;
- else
- dd->flags &= ~FLAGS_NEW_IV;
-
+ dd->ctx = ctx;
ctx->dd = dd;
- if (dd->ctx != ctx) {
- /* assign new context to device */
- dd->ctx = ctx;
- ctx->flags |= FLAGS_NEW_KEY;
- }

err = omap_aes_crypt_dma_start(dd);
if (err) {
@@ -747,7 +716,6 @@ static int omap_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,

memcpy(ctx->key, key, keylen);
ctx->keylen = keylen;
- ctx->flags |= FLAGS_NEW_KEY;

return 0;
}
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Eyal Reizer
2011-02-27 10:45:18 UTC
Permalink
This patch is again current omap-for-linus branch

Adds platform initialization for working with the WLAN module
attached to the omap3evm.
The patch includes MMC2 initialization, SDIO and control pins
muxing and platform device registration.

Signed-off-by: Eyal Reizer <***@ti.com>
---
arch/arm/mach-omap2/board-omap3evm.c | 32 ++++++++++++++++++++++----------
1 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 5364147..7341f96 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -411,7 +411,7 @@ static struct omap2_hsmmc_info mmc[] = {
#ifdef CONFIG_WL12XX_PLATFORM_DATA
{
.name = "wl1271",
- .mmc = 2,
+ .mmc = 2,
.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
.gpio_wp = -EINVAL,
.gpio_cd = -EINVAL,
@@ -603,10 +603,8 @@ static struct regulator_init_data omap3evm_vio = {
#define OMAP3EVM_WLAN_PMENA_GPIO (150)
#define OMAP3EVM_WLAN_IRQ_GPIO (149)

-static struct regulator_consumer_supply omap3evm_vmmc2_supply = {
- .supply = "vmmc",
- .dev_name = "mmci-omap-hs.1",
-};
+static struct regulator_consumer_supply omap3evm_vmmc2_supply =
+ REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1");

/* VMMC2 for driving the WL12xx module */
static struct regulator_init_data omap3evm_vmmc2 = {
@@ -627,7 +625,7 @@ static struct fixed_voltage_config omap3evm_vwlan = {
.init_data = &omap3evm_vmmc2,
};

-static struct platform_device omap3evm_vwlan_device = {
+static struct platform_device omap3evm_wlan_regulator = {
.name = "reg-fixed-voltage",
.id = 1,
.dev = {
@@ -637,8 +635,7 @@ static struct platform_device omap3evm_vwlan_device = {

struct wl12xx_platform_data omap3evm_wlan_data __initdata = {
.irq = OMAP_GPIO_IRQ(OMAP3EVM_WLAN_IRQ_GPIO),
- /* ref clock is 38.4 MHz */
- .board_ref_clock = 2,
+ .board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
};
#endif

@@ -765,7 +762,7 @@ static struct omap_board_mux omap35x_board_mux[] __initdata = {
OMAP_PIN_OFF_NONE),
#ifdef CONFIG_WL12XX_PLATFORM_DATA
/* WLAN IRQ - GPIO 149 */
- OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),

/* WLAN POWER ENABLE - GPIO 150 */
OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
@@ -801,6 +798,21 @@ static struct omap_board_mux omap36x_board_mux[] __initdata = {
OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+ /* WLAN IRQ - GPIO 149 */
+ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
+ /* WLAN POWER ENABLE - GPIO 150 */
+ OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ /* MMC2 SDIO pin muxes for WL12xx */
+ OMAP3_MUX(SDMMC2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+#endif

{ .reg_offset = OMAP_MUX_TERMINATOR },
};
@@ -871,7 +883,7 @@ static void __init omap3_evm_init(void)
/* WL12xx WLAN Init */
if (wl12xx_set_platform_data(&omap3evm_wlan_data))
pr_err("error setting wl12xx data\n");
- platform_device_register(&omap3evm_vwlan_device);
+ platform_device_register(&omap3evm_wlan_regulator);
#endif
}
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Tony Lindgren
2011-03-01 02:23:04 UTC
Permalink
Post by Eyal Reizer
This patch is again current omap-for-linus branch
Adds platform initialization for working with the WLAN module
attached to the omap3evm.
The patch includes MMC2 initialization, SDIO and control pins
muxing and platform device registration.
Thanks applying.

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Reizer, Eyal
2011-02-27 11:00:39 UTC
Permalink
As asked ,this patch is against current omap-for-linus branch

Adds platform initialization for working with the WLAN module
attached to the omap3evm.
The patch includes MMC2 initialization, SDIO and control pins
muxing and platform device registration.

Signed-off-by: Eyal Reizer <***@ti.com>
---
arch/arm/mach-omap2/board-omap3evm.c | 32 ++++++++++++++++++++++----------
1 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 5364147..7341f96 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -411,7 +411,7 @@ static struct omap2_hsmmc_info mmc[] = {
#ifdef CONFIG_WL12XX_PLATFORM_DATA
{
.name = "wl1271",
- .mmc = 2,
+ .mmc = 2,
.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
.gpio_wp = -EINVAL,
.gpio_cd = -EINVAL,
@@ -603,10 +603,8 @@ static struct regulator_init_data omap3evm_vio = {
#define OMAP3EVM_WLAN_PMENA_GPIO (150)
#define OMAP3EVM_WLAN_IRQ_GPIO (149)

-static struct regulator_consumer_supply omap3evm_vmmc2_supply = {
- .supply = "vmmc",
- .dev_name = "mmci-omap-hs.1",
-};
+static struct regulator_consumer_supply omap3evm_vmmc2_supply =
+ REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1");

/* VMMC2 for driving the WL12xx module */
static struct regulator_init_data omap3evm_vmmc2 = {
@@ -627,7 +625,7 @@ static struct fixed_voltage_config omap3evm_vwlan = {
.init_data = &omap3evm_vmmc2,
};

-static struct platform_device omap3evm_vwlan_device = {
+static struct platform_device omap3evm_wlan_regulator = {
.name = "reg-fixed-voltage",
.id = 1,
.dev = {
@@ -637,8 +635,7 @@ static struct platform_device omap3evm_vwlan_device = {

struct wl12xx_platform_data omap3evm_wlan_data __initdata = {
.irq = OMAP_GPIO_IRQ(OMAP3EVM_WLAN_IRQ_GPIO),
- /* ref clock is 38.4 MHz */
- .board_ref_clock = 2,
+ .board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
};
#endif

@@ -765,7 +762,7 @@ static struct omap_board_mux omap35x_board_mux[] __initdata = {
OMAP_PIN_OFF_NONE),
#ifdef CONFIG_WL12XX_PLATFORM_DATA
/* WLAN IRQ - GPIO 149 */
- OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),

/* WLAN POWER ENABLE - GPIO 150 */
OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
@@ -801,6 +798,21 @@ static struct omap_board_mux omap36x_board_mux[] __initdata = {
OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+ /* WLAN IRQ - GPIO 149 */
+ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
+ /* WLAN POWER ENABLE - GPIO 150 */
+ OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ /* MMC2 SDIO pin muxes for WL12xx */
+ OMAP3_MUX(SDMMC2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+#endif

{ .reg_offset = OMAP_MUX_TERMINATOR },
};
@@ -871,7 +883,7 @@ static void __init omap3_evm_init(void)
/* WL12xx WLAN Init */
if (wl12xx_set_platform_data(&omap3evm_wlan_data))
pr_err("error setting wl12xx data\n");
- platform_device_register(&omap3evm_vwlan_device);
+ platform_device_register(&omap3evm_wlan_regulator);
#endif
}
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
k***@dominion.thruhere.net
2011-05-20 10:59:07 UTC
Permalink
From: Koen Kooi <***@dominion.thruhere.net>

The USB enable GPIO has been inverted and the USER button moved.

Signed-off-by: Koen Kooi <***@dominion.thruhere.net>
---

Changes since v1:
Fixed more xM references

arch/arm/mach-omap2/board-omap3beagle.c | 32 +++++++++++++++++++++++-------
1 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 2de4b02..1eb1e8e 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -62,7 +62,9 @@
* AXBX = GPIO173, GPIO172, GPIO171: 1 1 1
* C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0
* C4 = GPIO173, GPIO172, GPIO171: 1 0 1
- * XM = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMA = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMB = GPIO173, GPIO172, GPIO171: 0 0 1
+ * XMC = GPIO173, GPIO172, GPIO171: 0 1 0
*/
enum {
OMAP3BEAGLE_BOARD_UNKN = 0,
@@ -70,6 +72,7 @@ enum {
OMAP3BEAGLE_BOARD_C1_3,
OMAP3BEAGLE_BOARD_C4,
OMAP3BEAGLE_BOARD_XM,
+ OMAP3BEAGLE_BOARD_XMC,
};

static u8 omap3_beagle_version;
@@ -124,9 +127,17 @@ static void __init omap3_beagle_init_rev(void)
printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
break;
+ case 1:
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM B\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
+ break;
+ case 2:
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
+ break;
default:
- printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd, assuming xM C or newer\n", beagle_rev);
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
}

return;
@@ -278,7 +289,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
{
int r;

- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
mmc[0].gpio_wp = -EINVAL;
} else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
(omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
@@ -298,7 +309,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
/* REVISIT: need ehci-omap hooks for external VBUS
* power switch and overcurrent detect
*/
- if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM && omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XMC) {
r = gpio_request(gpio + 1, "EHCI_nOC");
if (!r) {
r = gpio_direction_input(gpio + 1);
@@ -320,7 +331,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);

/* DVI reset GPIO is different between beagle revisions */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC)
beagle_dvi_device.reset_gpio = 129;
else
beagle_dvi_device.reset_gpio = 170;
@@ -334,7 +345,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
* P7/P8 revisions(prototype): Camera EN
* A2+ revisions (production): LDO (supplies DVI, serial, led blocks)
*/
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
r = gpio_request(gpio + 1, "nDVI_PWR_EN");
if (!r) {
r = gpio_direction_output(gpio + 1, 0);
@@ -625,7 +636,7 @@ static void __init beagle_opp_init(void)
}

/* Custom OPP enabled for XM */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
struct omap_hwmod *mh = omap_hwmod_lookup("mpu");
struct omap_hwmod *dh = omap_hwmod_lookup("iva");
struct device *dev;
@@ -665,6 +676,11 @@ static void __init omap3_beagle_init(void)
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap3_beagle_init_rev();
omap3_beagle_i2c_init();
+
+ if (cpu_is_omap3630()) {
+ gpio_buttons[0].gpio = 4;
+ }
+
platform_add_devices(omap3_beagle_devices,
ARRAY_SIZE(omap3_beagle_devices));
omap_display_init(&beagle_dss_data);
--
1.6.6.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Igor Grinberg
2011-05-22 14:30:42 UTC
Permalink
Hi Koen,
Post by k***@dominion.thruhere.net
The USB enable GPIO has been inverted and the USER button moved.
---
Fixed more xM references
arch/arm/mach-omap2/board-omap3beagle.c | 32 +++++++++++++++++++++++-------
1 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 2de4b02..1eb1e8e 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -62,7 +62,9 @@
* AXBX = GPIO173, GPIO172, GPIO171: 1 1 1
* C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0
* C4 = GPIO173, GPIO172, GPIO171: 1 0 1
- * XM = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMA = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMB = GPIO173, GPIO172, GPIO171: 0 0 1
+ * XMC = GPIO173, GPIO172, GPIO171: 0 1 0
*/
enum {
OMAP3BEAGLE_BOARD_UNKN = 0,
@@ -70,6 +72,7 @@ enum {
OMAP3BEAGLE_BOARD_C1_3,
OMAP3BEAGLE_BOARD_C4,
OMAP3BEAGLE_BOARD_XM,
+ OMAP3BEAGLE_BOARD_XMC,
};
static u8 omap3_beagle_version;
@@ -124,9 +127,17 @@ static void __init omap3_beagle_init_rev(void)
printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
break;
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM B\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
+ break;
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
+ break;
- printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd, assuming xM C or newer\n", beagle_rev);
Please, break this line so it will be < 80
and also all occurrences below.
Post by k***@dominion.thruhere.net
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
}
return;
@@ -278,7 +289,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
{
int r;
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
There is no real need to make it > 80
Post by k***@dominion.thruhere.net
mmc[0].gpio_wp = -EINVAL;
} else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
(omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
@@ -298,7 +309,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
/* REVISIT: need ehci-omap hooks for external VBUS
* power switch and overcurrent detect
*/
- if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM && omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XMC) {
r = gpio_request(gpio + 1, "EHCI_nOC");
if (!r) {
r = gpio_direction_input(gpio + 1);
@@ -320,7 +331,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
/* DVI reset GPIO is different between beagle revisions */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC)
beagle_dvi_device.reset_gpio = 129;
else
beagle_dvi_device.reset_gpio = 170;
@@ -334,7 +345,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
* P7/P8 revisions(prototype): Camera EN
* A2+ revisions (production): LDO (supplies DVI, serial, led blocks)
*/
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
r = gpio_request(gpio + 1, "nDVI_PWR_EN");
if (!r) {
r = gpio_direction_output(gpio + 1, 0);
@@ -625,7 +636,7 @@ static void __init beagle_opp_init(void)
}
/* Custom OPP enabled for XM */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
struct omap_hwmod *mh = omap_hwmod_lookup("mpu");
struct omap_hwmod *dh = omap_hwmod_lookup("iva");
struct device *dev;
@@ -665,6 +676,11 @@ static void __init omap3_beagle_init(void)
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap3_beagle_init_rev();
omap3_beagle_i2c_init();
+
+ if (cpu_is_omap3630()) {
+ gpio_buttons[0].gpio = 4;
+ }
can't this kind of check be used in all the XM checks above?
Post by k***@dominion.thruhere.net
+
platform_add_devices(omap3_beagle_devices,
ARRAY_SIZE(omap3_beagle_devices));
omap_display_init(&beagle_dss_data);
--
Regards,
Igor.

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Koen Kooi
2011-05-23 17:51:11 UTC
Permalink
Post by Igor Grinberg
Hi Koen,
Post by k***@dominion.thruhere.net
The USB enable GPIO has been inverted and the USER button moved.
---
Fixed more xM references
arch/arm/mach-omap2/board-omap3beagle.c | 32 +++++++++++++++++++++++-------
1 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 2de4b02..1eb1e8e 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -62,7 +62,9 @@
* AXBX = GPIO173, GPIO172, GPIO171: 1 1 1
* C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0
* C4 = GPIO173, GPIO172, GPIO171: 1 0 1
- * XM = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMA = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMB = GPIO173, GPIO172, GPIO171: 0 0 1
+ * XMC = GPIO173, GPIO172, GPIO171: 0 1 0
*/
enum {
OMAP3BEAGLE_BOARD_UNKN = 0,
@@ -70,6 +72,7 @@ enum {
OMAP3BEAGLE_BOARD_C1_3,
OMAP3BEAGLE_BOARD_C4,
OMAP3BEAGLE_BOARD_XM,
+ OMAP3BEAGLE_BOARD_XMC,
};
static u8 omap3_beagle_version;
@@ -124,9 +127,17 @@ static void __init omap3_beagle_init_rev(void)
printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
break;
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM B\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
+ break;
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
+ break;
- printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd, assuming xM C or newer\n", beagle_rev);
Please, break this line so it will be < 80
and also all occurrences below.
Post by k***@dominion.thruhere.net
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
}
return;
@@ -278,7 +289,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
{
int r;
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
There is no real need to make it > 80
Post by k***@dominion.thruhere.net
mmc[0].gpio_wp = -EINVAL;
} else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
(omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
@@ -298,7 +309,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
/* REVISIT: need ehci-omap hooks for external VBUS
* power switch and overcurrent detect
*/
- if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM && omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XMC) {
r = gpio_request(gpio + 1, "EHCI_nOC");
if (!r) {
r = gpio_direction_input(gpio + 1);
@@ -320,7 +331,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
/* DVI reset GPIO is different between beagle revisions */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC)
beagle_dvi_device.reset_gpio = 129;
else
beagle_dvi_device.reset_gpio = 170;
@@ -334,7 +345,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
* P7/P8 revisions(prototype): Camera EN
* A2+ revisions (production): LDO (supplies DVI, serial, led blocks)
*/
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
r = gpio_request(gpio + 1, "nDVI_PWR_EN");
if (!r) {
r = gpio_direction_output(gpio + 1, 0);
@@ -625,7 +636,7 @@ static void __init beagle_opp_init(void)
}
/* Custom OPP enabled for XM */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM || omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XMC) {
struct omap_hwmod *mh = omap_hwmod_lookup("mpu");
struct omap_hwmod *dh = omap_hwmod_lookup("iva");
struct device *dev;
@@ -665,6 +676,11 @@ static void __init omap3_beagle_init(void)
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap3_beagle_init_rev();
omap3_beagle_i2c_init();
+
+ if (cpu_is_omap3630()) {
+ gpio_buttons[0].gpio = 4;
+ }
can't this kind of check be used in all the XM checks above?
Not in every case, I'll see which ones can be converted to this simpler check. I'll respin the patch with your other comments addressed.

regards

Koen--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
k***@dominion.thruhere.net
2011-05-24 09:48:26 UTC
Permalink
From: Koen Kooi <***@dominion.thruhere.net>

The USB enable GPIO has been inverted and the USER button moved.

Signed-off-by: Koen Kooi <***@dominion.thruhere.net>
---

Changes since v1:
* Limited line width to 80 chars max
* changed XM || XMC to cpu_is_omap3630()

arch/arm/mach-omap2/board-omap3beagle.c | 34 +++++++++++++++++++++++-------
1 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 33007fd..ffd2209 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -62,7 +62,9 @@
* AXBX = GPIO173, GPIO172, GPIO171: 1 1 1
* C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0
* C4 = GPIO173, GPIO172, GPIO171: 1 0 1
- * XM = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMA = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMB = GPIO173, GPIO172, GPIO171: 0 0 1
+ * XMC = GPIO173, GPIO172, GPIO171: 0 1 0
*/
enum {
OMAP3BEAGLE_BOARD_UNKN = 0,
@@ -70,6 +72,7 @@ enum {
OMAP3BEAGLE_BOARD_C1_3,
OMAP3BEAGLE_BOARD_C4,
OMAP3BEAGLE_BOARD_XM,
+ OMAP3BEAGLE_BOARD_XMC,
};

static u8 omap3_beagle_version;
@@ -124,9 +127,18 @@ static void __init omap3_beagle_init_rev(void)
printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
break;
+ case 1:
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM B\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
+ break;
+ case 2:
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
+ break;
default:
- printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ printk(KERN_INFO
+ "OMAP3 Beagle Rev: unknown %hd, assuming xM C or newer\n", beagle_rev);
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
}

return;
@@ -278,7 +290,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
{
int r;

- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (cpu_is_omap3630()) {
mmc[0].gpio_wp = -EINVAL;
} else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
(omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
@@ -298,7 +310,8 @@ static int beagle_twl_gpio_setup(struct device *dev,
/* REVISIT: need ehci-omap hooks for external VBUS
* power switch and overcurrent detect
*/
- if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM) {
+ if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM
+ && omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XMC) {
r = gpio_request(gpio + 1, "EHCI_nOC");
if (!r) {
r = gpio_direction_input(gpio + 1);
@@ -320,7 +333,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);

/* DVI reset GPIO is different between beagle revisions */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
+ if (cpu_is_omap3630())
beagle_dvi_device.reset_gpio = 129;
else
beagle_dvi_device.reset_gpio = 170;
@@ -334,7 +347,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
* P7/P8 revisions(prototype): Camera EN
* A2+ revisions (production): LDO (supplies DVI, serial, led blocks)
*/
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (cpu_is_omap3630()) {
r = gpio_request(gpio + 1, "nDVI_PWR_EN");
if (!r) {
r = gpio_direction_output(gpio + 1, 0);
@@ -619,7 +632,7 @@ static void __init beagle_opp_init(void)
}

/* Custom OPP enabled for XM */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (cpu_is_omap3630()) {
struct omap_hwmod *mh = omap_hwmod_lookup("mpu");
struct omap_hwmod *dh = omap_hwmod_lookup("iva");
struct device *dev;
@@ -659,6 +672,11 @@ static void __init omap3_beagle_init(void)
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap3_beagle_init_rev();
omap3_beagle_i2c_init();
+
+ if (cpu_is_omap3630()) {
+ gpio_buttons[0].gpio = 4;
+ }
+
platform_add_devices(omap3_beagle_devices,
ARRAY_SIZE(omap3_beagle_devices));
omap_display_init(&beagle_dss_data);
--
1.6.6.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Koen Kooi
2011-05-27 13:32:13 UTC
Permalink
The USB enable GPIO has been inverted again and the USER button moved

Signed-off-by: Koen Kooi <***@dominion.thruhere.net>
---
Changes since v2:
* fixed indentation error checkpatch missed

Changes since v1:
* updated against mainline to take Igors gpio cleanup into account
* removed xM rev B checks, no boards with that ID were ever produced, rev B boards show up as rev A
* double checked whitespace:

total: 0 errors, 0 warnings, 89 lines checked
patches/0001-OMAP3-beagle-add-support-for-beagleboard-xM-revision.patch has no obvious style problems and is ready for submission.

arch/arm/mach-omap2/board-omap3beagle.c | 31 +++++++++++++++++++++++--------
1 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index be71426..81fff9d 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -63,7 +63,9 @@
* AXBX = GPIO173, GPIO172, GPIO171: 1 1 1
* C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0
* C4 = GPIO173, GPIO172, GPIO171: 1 0 1
- * XM = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMA = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMB = GPIO173, GPIO172, GPIO171: 0 0 1 - unused
+ * XMC = GPIO173, GPIO172, GPIO171: 0 1 0
*/
enum {
OMAP3BEAGLE_BOARD_UNKN = 0,
@@ -71,6 +73,7 @@ enum {
OMAP3BEAGLE_BOARD_C1_3,
OMAP3BEAGLE_BOARD_C4,
OMAP3BEAGLE_BOARD_XM,
+ OMAP3BEAGLE_BOARD_XMC,
};

static u8 omap3_beagle_version;
@@ -123,9 +126,13 @@ static void __init omap3_beagle_init_rev(void)
printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
break;
+ case 2:
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
+ break;
default:
printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
}
}

@@ -253,7 +260,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
{
int r, usb_pwr_level;

- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (cpu_is_omap3630()) {
mmc[0].gpio_wp = -EINVAL;
} else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
(omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
@@ -275,11 +282,10 @@ static int beagle_twl_gpio_setup(struct device *dev,
* high / others active low)
* DVI reset GPIO is different between beagle revisions
*/
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
- usb_pwr_level = GPIOF_OUT_INIT_HIGH;
+ if (cpu_is_omap3630()) {
beagle_dvi_device.reset_gpio = 129;
/*
- * gpio + 1 on Xm controls the TFP410's enable line (active low)
+ * gpio + 1 on xM controls the TFP410's enable line (active low)
* gpio + 2 control varies depending on the board rev as below:
* P7/P8 revisions(prototype): Camera EN
* A2+ revisions (production): LDO (DVI, serial, led blocks)
@@ -295,7 +301,6 @@ static int beagle_twl_gpio_setup(struct device *dev,
pr_err("%s: unable to configure DVI_LDO_EN\n",
__func__);
} else {
- usb_pwr_level = GPIOF_OUT_INIT_LOW;
beagle_dvi_device.reset_gpio = 170;
/*
* REVISIT: need ehci-omap hooks for external VBUS
@@ -305,6 +310,12 @@ static int beagle_twl_gpio_setup(struct device *dev,
pr_err("%s: unable to configure EHCI_nOC\n", __func__);
}

+ /* Only xM rev A and xM rev B use active high */
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
+ usb_pwr_level = GPIOF_OUT_INIT_HIGH;
+ else
+ usb_pwr_level = GPIOF_OUT_INIT_LOW;
+
gpio_request_one(gpio + TWL4030_GPIO_MAX, usb_pwr_level, "nEN_USB_PWR");

/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
@@ -525,7 +536,7 @@ static void __init beagle_opp_init(void)
}

/* Custom OPP enabled for XM */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (cpu_is_omap3630()) {
struct omap_hwmod *mh = omap_hwmod_lookup("mpu");
struct omap_hwmod *dh = omap_hwmod_lookup("iva");
struct device *dev;
@@ -565,6 +576,10 @@ static void __init omap3_beagle_init(void)
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap3_beagle_init_rev();
omap3_beagle_i2c_init();
+
+ if (cpu_is_omap3630())
+ gpio_buttons[0].gpio = 4;
+
platform_add_devices(omap3_beagle_devices,
ARRAY_SIZE(omap3_beagle_devices));
omap_display_init(&beagle_dss_data);
--
1.6.6.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Koen Kooi
2011-05-27 13:33:36 UTC
Permalink
That was meant to say '[PATCH v3]', sorry about that.
Post by Koen Kooi
The USB enable GPIO has been inverted again and the USER button moved
---
* fixed indentation error checkpatch missed
* updated against mainline to take Igors gpio cleanup into account
* removed xM rev B checks, no boards with that ID were ever produced, rev B boards show up as rev A
total: 0 errors, 0 warnings, 89 lines checked
patches/0001-OMAP3-beagle-add-support-for-beagleboard-xM-revision.patch has no obvious style problems and is ready for submission.
arch/arm/mach-omap2/board-omap3beagle.c | 31 +++++++++++++++++++++++--------
1 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index be71426..81fff9d 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -63,7 +63,9 @@
* AXBX = GPIO173, GPIO172, GPIO171: 1 1 1
* C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0
* C4 = GPIO173, GPIO172, GPIO171: 1 0 1
- * XM = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMA = GPIO173, GPIO172, GPIO171: 0 0 0
+ * XMB = GPIO173, GPIO172, GPIO171: 0 0 1 - unused
+ * XMC = GPIO173, GPIO172, GPIO171: 0 1 0
*/
enum {
OMAP3BEAGLE_BOARD_UNKN = 0,
@@ -71,6 +73,7 @@ enum {
OMAP3BEAGLE_BOARD_C1_3,
OMAP3BEAGLE_BOARD_C4,
OMAP3BEAGLE_BOARD_XM,
+ OMAP3BEAGLE_BOARD_XMC,
};
static u8 omap3_beagle_version;
@@ -123,9 +126,13 @@ static void __init omap3_beagle_init_rev(void)
printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
break;
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
+ break;
printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
}
}
@@ -253,7 +260,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
{
int r, usb_pwr_level;
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (cpu_is_omap3630()) {
mmc[0].gpio_wp = -EINVAL;
} else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
(omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
@@ -275,11 +282,10 @@ static int beagle_twl_gpio_setup(struct device *dev,
* high / others active low)
* DVI reset GPIO is different between beagle revisions
*/
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
- usb_pwr_level = GPIOF_OUT_INIT_HIGH;
+ if (cpu_is_omap3630()) {
beagle_dvi_device.reset_gpio = 129;
/*
- * gpio + 1 on Xm controls the TFP410's enable line (active low)
+ * gpio + 1 on xM controls the TFP410's enable line (active low)
* P7/P8 revisions(prototype): Camera EN
* A2+ revisions (production): LDO (DVI, serial, led blocks)
@@ -295,7 +301,6 @@ static int beagle_twl_gpio_setup(struct device *dev,
pr_err("%s: unable to configure DVI_LDO_EN\n",
__func__);
} else {
- usb_pwr_level = GPIOF_OUT_INIT_LOW;
beagle_dvi_device.reset_gpio = 170;
/*
* REVISIT: need ehci-omap hooks for external VBUS
@@ -305,6 +310,12 @@ static int beagle_twl_gpio_setup(struct device *dev,
pr_err("%s: unable to configure EHCI_nOC\n", __func__);
}
+ /* Only xM rev A and xM rev B use active high */
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
+ usb_pwr_level = GPIOF_OUT_INIT_HIGH;
+ else
+ usb_pwr_level = GPIOF_OUT_INIT_LOW;
+
gpio_request_one(gpio + TWL4030_GPIO_MAX, usb_pwr_level, "nEN_USB_PWR");
/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
@@ -525,7 +536,7 @@ static void __init beagle_opp_init(void)
}
/* Custom OPP enabled for XM */
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (cpu_is_omap3630()) {
struct omap_hwmod *mh = omap_hwmod_lookup("mpu");
struct omap_hwmod *dh = omap_hwmod_lookup("iva");
struct device *dev;
@@ -565,6 +576,10 @@ static void __init omap3_beagle_init(void)
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap3_beagle_init_rev();
omap3_beagle_i2c_init();
+
+ if (cpu_is_omap3630())
+ gpio_buttons[0].gpio = 4;
+
platform_add_devices(omap3_beagle_devices,
ARRAY_SIZE(omap3_beagle_devices));
omap_display_init(&beagle_dss_data);
--
1.6.6.1
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Tony Lindgren
2011-05-30 14:34:11 UTC
Permalink
Hi,
Post by Koen Kooi
@@ -123,9 +126,13 @@ static void __init omap3_beagle_init_rev(void)
printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
break;
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
+ break;
printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
}
}
Maybe just set up static struct omap3_beagle that contains the
various things to initialize. Then initialize it in omap3_beagle_init_rev
above.

Otherwise we'll end up adding more and more omap3_beagle_get_rev and
cpu_is_omap tests to this file and it will become hard to maintain.
Post by Koen Kooi
@@ -253,7 +260,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
{
int r, usb_pwr_level;
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (cpu_is_omap3630()) {
mmc[0].gpio_wp = -EINVAL;
} else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
(omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
This would become:

mmc[0].gpio_wp = beagle.gpio_wp;
Post by Koen Kooi
@@ -275,11 +282,10 @@ static int beagle_twl_gpio_setup(struct device *dev,
* high / others active low)
* DVI reset GPIO is different between beagle revisions
*/
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
- usb_pwr_level = GPIOF_OUT_INIT_HIGH;
+ if (cpu_is_omap3630()) {
beagle_dvi_device.reset_gpio = 129;
/*
- * gpio + 1 on Xm controls the TFP410's enable line (active low)
+ * gpio + 1 on xM controls the TFP410's enable line (active low)
* P7/P8 revisions(prototype): Camera EN
* A2+ revisions (production): LDO (DVI, serial, led blocks)
This would be just:

usb_pwr_level = beagle.usb_pwr_level;

And so on.

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Koen Kooi
2011-05-31 18:13:45 UTC
Permalink
Post by Tony Lindgren
Hi,
Post by Koen Kooi
@@ -123,9 +126,13 @@ static void __init omap3_beagle_init_rev(void)
printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
break;
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
+ break;
printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
}
}
Maybe just set up static struct omap3_beagle that contains the
various things to initialize. Then initialize it in omap3_beagle_init_rev
above.
Otherwise we'll end up adding more and more omap3_beagle_get_rev and
cpu_is_omap tests to this file and it will become hard to maintain.
Post by Koen Kooi
@@ -253,7 +260,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
{
int r, usb_pwr_level;
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (cpu_is_omap3630()) {
mmc[0].gpio_wp = -EINVAL;
} else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
(omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
mmc[0].gpio_wp = beagle.gpio_wp;
Post by Koen Kooi
@@ -275,11 +282,10 @@ static int beagle_twl_gpio_setup(struct device *dev,
* high / others active low)
* DVI reset GPIO is different between beagle revisions
*/
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
- usb_pwr_level = GPIOF_OUT_INIT_HIGH;
+ if (cpu_is_omap3630()) {
beagle_dvi_device.reset_gpio = 129;
/*
- * gpio + 1 on Xm controls the TFP410's enable line (active low)
+ * gpio + 1 on xM controls the TFP410's enable line (active low)
* P7/P8 revisions(prototype): Camera EN
* A2+ revisions (production): LDO (DVI, serial, led blocks)
usb_pwr_level = beagle.usb_pwr_level;
And so on.
Tony, thanks for the feedback! The change you want is a bit too much for my C knowledge, but Joel will but picking it up from here.

regards,

Koen--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Tony Lindgren
2011-06-01 06:43:55 UTC
Permalink
Post by Koen Kooi
Post by Tony Lindgren
Hi,
Post by Koen Kooi
@@ -123,9 +126,13 @@ static void __init omap3_beagle_init_rev(void)
printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
break;
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
+ break;
printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
}
}
Maybe just set up static struct omap3_beagle that contains the
various things to initialize. Then initialize it in omap3_beagle_init_rev
above.
Otherwise we'll end up adding more and more omap3_beagle_get_rev and
cpu_is_omap tests to this file and it will become hard to maintain.
Post by Koen Kooi
@@ -253,7 +260,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
{
int r, usb_pwr_level;
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ if (cpu_is_omap3630()) {
mmc[0].gpio_wp = -EINVAL;
} else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
(omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
mmc[0].gpio_wp = beagle.gpio_wp;
Post by Koen Kooi
@@ -275,11 +282,10 @@ static int beagle_twl_gpio_setup(struct device *dev,
* high / others active low)
* DVI reset GPIO is different between beagle revisions
*/
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
- usb_pwr_level = GPIOF_OUT_INIT_HIGH;
+ if (cpu_is_omap3630()) {
beagle_dvi_device.reset_gpio = 129;
/*
- * gpio + 1 on Xm controls the TFP410's enable line (active low)
+ * gpio + 1 on xM controls the TFP410's enable line (active low)
* P7/P8 revisions(prototype): Camera EN
* A2+ revisions (production): LDO (DVI, serial, led blocks)
usb_pwr_level = beagle.usb_pwr_level;
And so on.
Tony, thanks for the feedback! The change you want is a bit too much for my C knowledge, but Joel will but picking it up from here.
Hmm, not much there to it actually :) I'm sure you too can do it
little help from Joel.

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Shahar Lev
2011-06-14 12:16:28 UTC
Permalink
Add Kconfig entries indicating the existence of omap3evm's
wlan/bt wl12xx daughter card (see
http://mistralsolutions.com/component/jumi/Download_Common_Code.html?docid=298),
and the exact reference clock type that the wl12xx device is hardwired
to (the wl12xx driver must know this).

In addition, start using CONFIG_OMAP3EVM_MISTRAL_WL12XX in
the omap3evm's board file instead of CONFIG_WL12XX_PLATFORM_DATA,
because the latter only indicates that the driver is being built, and
shouldn't be used to assume the existence of extension cards.

Signed-off-by: Shahar Lev <***@wizery.com>
---
arch/arm/mach-omap2/Kconfig | 23 +++++++++++++++++++++++
arch/arm/mach-omap2/board-omap3evm.c | 12 ++++++------
2 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 19d5891..8ef012d 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -342,6 +342,29 @@ config OMAP3_SDRC_AC_TIMING
wish to say no. Selecting yes without understanding what is
going on could result in system crashes;

+config OMAP3EVM_MISTRAL_WL12XX
+ bool "Enable Mistral WL12XX daughter board support"
+ depends on MACH_OMAP3EVM
+ help
+ Support for the Mistral WL12XX daughter board.
+ This extension board which supports both WLAN and Bluetooth.
+ Specifically, for WL1271, more info can be found at
+ http://mistralsolutions.com/component/jumi/Download_Common_Code.html?docid=298
+
+config OMAP3EVM_MISTRAL_WL12XX_REFCLOCK
+ int "Ref clock value"
+ range 0 5
+ depends on OMAP3EVM_MISTRAL_WL12XX
+ default 2
+ help
+ Set ref clock value for the Mistral WL12XX daughter board.
+ Select 0 for 19.2 MHz.
+ Select 1 for 26 MHz.
+ Select 2 for 38.4 MHz.
+ Select 3 for 52 MHz.
+ Select 4 for 38.4 MHz, XTAL.
+ Select 5 for 26 MHz, XTAL.
+
endmenu

endif
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index b4d4346..23f12ff 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -318,7 +318,7 @@ static struct omap2_hsmmc_info mmc[] = {
.gpio_cd = -EINVAL,
.gpio_wp = 63,
},
-#ifdef CONFIG_WL12XX_PLATFORM_DATA
+#ifdef CONFIG_OMAP3EVM_MISTRAL_WL12XX
{
.name = "wl1271",
.mmc = 2,
@@ -506,7 +506,7 @@ static struct regulator_init_data omap3evm_vio = {
.consumer_supplies = &omap3evm_vio_supply,
};

-#ifdef CONFIG_WL12XX_PLATFORM_DATA
+#ifdef CONFIG_OMAP3EVM_MISTRAL_WL12XX

#define OMAP3EVM_WLAN_PMENA_GPIO (150)
#define OMAP3EVM_WLAN_IRQ_GPIO (149)
@@ -543,7 +543,7 @@ static struct platform_device omap3evm_wlan_regulator = {

struct wl12xx_platform_data omap3evm_wlan_data __initdata = {
.irq = OMAP_GPIO_IRQ(OMAP3EVM_WLAN_IRQ_GPIO),
- .board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
+ .board_ref_clock = CONFIG_OMAP3EVM_MISTRAL_WL12XX_REFCLOCK,
};
#endif

@@ -606,7 +606,7 @@ static struct omap_board_mux omap35x_board_mux[] __initdata = {
OMAP_PIN_OFF_NONE),
OMAP3_MUX(GPMC_WAIT2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
OMAP_PIN_OFF_NONE),
-#ifdef CONFIG_WL12XX_PLATFORM_DATA
+#ifdef CONFIG_OMAP3EVM_MISTRAL_WL12XX
/* WLAN IRQ - GPIO 149 */
OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),

@@ -644,7 +644,7 @@ static struct omap_board_mux omap36x_board_mux[] __initdata = {
OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
-#ifdef CONFIG_WL12XX_PLATFORM_DATA
+#ifdef CONFIG_OMAP3EVM_MISTRAL_WL12XX
/* WLAN IRQ - GPIO 149 */
OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),

@@ -726,7 +726,7 @@ static void __init omap3_evm_init(void)
omap3evm_init_smsc911x();
omap3_evm_display_init();

-#ifdef CONFIG_WL12XX_PLATFORM_DATA
+#ifdef CONFIG_OMAP3EVM_MISTRAL_WL12XX
/* WL12xx WLAN Init */
if (wl12xx_set_platform_data(&omap3evm_wlan_data))
pr_err("error setting wl12xx data\n");
--
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Tony Lindgren
2011-06-14 12:34:00 UTC
Permalink
Post by Shahar Lev
+config OMAP3EVM_MISTRAL_WL12XX
+ bool "Enable Mistral WL12XX daughter board support"
+ depends on MACH_OMAP3EVM
+ help
+ Support for the Mistral WL12XX daughter board.
+ This extension board which supports both WLAN and Bluetooth.
+ Specifically, for WL1271, more info can be found at
+ http://mistralsolutions.com/component/jumi/Download_Common_Code.html?docid=298
+
+config OMAP3EVM_MISTRAL_WL12XX_REFCLOCK
+ int "Ref clock value"
+ range 0 5
+ depends on OMAP3EVM_MISTRAL_WL12XX
+ default 2
+ help
+ Set ref clock value for the Mistral WL12XX daughter board.
+ Select 0 for 19.2 MHz.
+ Select 1 for 26 MHz.
+ Select 2 for 38.4 MHz.
+ Select 3 for 52 MHz.
+ Select 4 for 38.4 MHz, XTAL.
+ Select 5 for 26 MHz, XTAL.
+
This your should try to remove as it won't work nicely for supporting
various boards with the same kernel as we already do with
omap2plus_defconfig.

Can you somehow detect the daughter board dynamically and then
set the flags?

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Shahar Lev
2011-06-14 13:26:06 UTC
Permalink
Post by Tony Lindgren
This your should try to remove as it won't work nicely for supporting
various boards with the same kernel as we already do with
omap2plus_defconfig.
Can you somehow detect the daughter board dynamically and then
set the flags?
We thought about multi-board kernels, but unfortunately have no
better solution, since there is no dynamic way to probe these cards.
Even worse, these cards sometimes come with different clocks in them,
hence the 2nd OMAP3EVM_MISTRAL_WL12XX_REFCLOCK entry we had to
introduce...

Maybe we should add two bootargs with which the user can override this
Kconfig configuration? This should allow using the same kernel binary
with different omap3evm boards.

It's a bit cumbersome though..
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Tony Lindgren
2011-06-14 13:55:19 UTC
Permalink
Post by Shahar Lev
Post by Tony Lindgren
This your should try to remove as it won't work nicely for supporting
various boards with the same kernel as we already do with
omap2plus_defconfig.
Can you somehow detect the daughter board dynamically and then
set the flags?
We thought about multi-board kernels, but unfortunately have no
better solution, since there is no dynamic way to probe these cards.
Even worse, these cards sometimes come with different clocks in them,
hence the 2nd OMAP3EVM_MISTRAL_WL12XX_REFCLOCK entry we had to
introduce...
Maybe we should add two bootargs with which the user can override this
Kconfig configuration? This should allow using the same kernel binary
with different omap3evm boards.
It's a bit cumbersome though..
Yes cmdline should do the trick until we have devicetree data
available..

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Vitaly Wool
2011-06-16 12:20:27 UTC
Permalink
Hi Shahar, Tony,
Post by Shahar Lev
Post by Tony Lindgren
This your should try to remove as it won't work nicely for supporting
various boards with the same kernel as we already do with
omap2plus_defconfig.
Can you somehow detect the daughter board dynamically and then
set the flags?
We thought about multi-board kernels, but unfortunately have no
better solution, since there is no dynamic way to probe these cards.
Even worse, these cards sometimes come with different clocks in them,
hence the 2nd OMAP3EVM_MISTRAL_WL12XX_REFCLOCK entry we had to
introduce...
Maybe we should add two bootargs with which the user can override this
Kconfig configuration? This should allow using the same kernel binary
with different omap3evm boards.
You won't need Kconfig parameters then. Just have module parameters
and supply whatever default values you find reasonable.

~Vitaly
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Premi, Sanjeev
2011-06-16 09:53:08 UTC
Permalink
Post by Pillai, Manikandan
-----Original Message-----
Sent: Tuesday, June 14, 2011 5:46 PM
Cc: linux-arm; Tony Lindgren; Shahar Lev
Subject: [PATCH] omap3evm: Add Mistral WL12XX config support
Add Kconfig entries indicating the existence of omap3evm's
wlan/bt wl12xx daughter card (see
http://mistralsolutions.com/component/jumi/Download_Common_Cod
e.html?docid=298),
and the exact reference clock type that the wl12xx device is hardwired
to (the wl12xx driver must know this).
In addition, start using CONFIG_OMAP3EVM_MISTRAL_WL12XX in
the omap3evm's board file instead of CONFIG_WL12XX_PLATFORM_DATA,
because the latter only indicates that the driver is being built, and
shouldn't be used to assume the existence of extension cards.
---
arch/arm/mach-omap2/Kconfig | 23 +++++++++++++++++++++++
arch/arm/mach-omap2/board-omap3evm.c | 12 ++++++------
2 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 19d5891..8ef012d 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -342,6 +342,29 @@ config OMAP3_SDRC_AC_TIMING
wish to say no. Selecting yes without understanding what is
going on could result in system crashes;
+config OMAP3EVM_MISTRAL_WL12XX
[sp] Could this be renamed simply as: OMAP3EVM_WL12XX?
OR is there a specific reason to add vendor/manufacturers' name
to the defintion?

~sanjeev

[snip]...[snip]
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Shahar Lev
2011-06-16 18:37:22 UTC
Permalink
Post by Premi, Sanjeev
[sp] Could this be renamed simply as: OMAP3EVM_WL12XX?
=A0 =A0 OR is there a specific reason to add vendor/manufacturers' na=
me
Post by Premi, Sanjeev
=A0 =A0 to the defintion?
I don't mind changing it.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" i=
n
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-06-24 11:05:46 UTC
Permalink
Hi Paul,

Here is the series that finally add the management of the modulemode
directly from hwmod fmwk instead of using a fake clock node to represent
the IP.

A second series will clean most of the remaining data from the clock data
file. Before that I have to rebase Rajendra's series to control the
clockdomain from the hwmod framework, otherwise the modules will
not be enabled properly since their clockdomain will not be changed
to SW_SUP during enable.

The series is based on for_3.0.1/3_hwmod_fixes and tested
on OMAP4430 ES2.1 + SDP. It should not affect OMAP2 & 3, but some testing
are definitively needed.

The patches are available here:
git://gitorious.org/omap-pm/linux.git for_3.0.1/4_hwmod_modulemode

Regards,
Benoit


Benoit Cousson (13):
OMAP4: hwmod: Add clock domain attribute
OMAP2+: hwmod: Init clkdm field at boot time
OMAP4: hwmod: Replace CLKCTRL absolute address with offset macros
OMAP: hwmod: Wait the idle status to be disabled
OMAP2+: hwmod: Replace clkdm access from main_clk using hwmod attribute
OMAP4: hwmod: Replace RSTCTRL absolute address with offset macros
OMAP4: prm: Replace warm reset API with the offset based version
OMAP4: prm: Remove deprecated functions
OMAP4: hwmod data: Align interconnect format with regular modules
OMAP4: hwmod data: Add PRM context register offset
OMAP4: hwmod data: Add modulemode entry in omap_hwmod structure
OMAP4: cm: Add two new APIs for modulemode control
OMAP4: hwmod: Introduce the module control in hwmod control

Nayak, Rajendra (1):
OMAP2+: clockdomain: Add an api to read idle mode

arch/arm/mach-omap2/clockdomain.c | 21 ++
arch/arm/mach-omap2/clockdomain.h | 3 +
arch/arm/mach-omap2/cm44xx.h | 3 +-
arch/arm/mach-omap2/cminst44xx.c | 84 +++++-
arch/arm/mach-omap2/cminst44xx.h | 8 +-
arch/arm/mach-omap2/omap_hwmod.c | 196 +++++++++--
arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 458 ++++++++++++++++++++------
arch/arm/mach-omap2/prm44xx.c | 145 +--------
arch/arm/mach-omap2/prm44xx.h | 6 -
arch/arm/mach-omap2/prminst44xx.c | 108 ++++++-
arch/arm/mach-omap2/prminst44xx.h | 10 +-
arch/arm/plat-omap/include/plat/omap_hwmod.h | 14 +-
12 files changed, 757 insertions(+), 299 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Cousson, Benoit
2011-06-24 12:32:40 UTC
Permalink
Grrr, one patch escaped from the next series and ended up here...
Post by Benoit Cousson
OMAP2+: clockdomain: Add an api to read idle mode
That one was re-sent in the proper series:
[PATCH v2 0/7] Fix module-mode enable sequence on OMAP4

The GIT trees are correct.

Benoit


--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-06-24 11:05:47 UTC
Permalink
In OMAP PRCM terminology, the clock domain is defined as a group of IPs
that share some clocks and most of the time an interface clock.
Every IP does belong to a clockdomain.
For the moment the clock domain attribute is affected to a clock node.
The issue with that approach, is that a clock might or not belong to a
clock domain. Moreover during module transition, it is up to a module
to handle properly the clock domain state and not to a clock node.

Create a clkdm_name attribute to provide this information per hwmod.

Future cleanup series with remove that information from the OMAP4 clock
when it is relevant.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Cc: Paul Walmsley <***@pwsan.com>
Cc: Rajendra Nayak <***@ti.com>
---
arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 82 ++++++++++++++++++++++++++
arch/arm/plat-omap/include/plat/omap_hwmod.h | 1 +
2 files changed, 83 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index c531611..63ba19f 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -120,6 +120,7 @@ static struct omap_hwmod_irq_info omap44xx_dmm_irqs[] = {
static struct omap_hwmod omap44xx_dmm_hwmod = {
.name = "dmm",
.class = &omap44xx_dmm_hwmod_class,
+ .clkdm_name = "l3_emif_clkdm",
.slaves = omap44xx_dmm_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dmm_slaves),
.mpu_irqs = omap44xx_dmm_irqs,
@@ -171,6 +172,7 @@ static struct omap_hwmod_ocp_if *omap44xx_emif_fw_slaves[] = {
static struct omap_hwmod omap44xx_emif_fw_hwmod = {
.name = "emif_fw",
.class = &omap44xx_emif_fw_hwmod_class,
+ .clkdm_name = "l3_emif_clkdm",
.slaves = omap44xx_emif_fw_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_emif_fw_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -210,6 +212,7 @@ static struct omap_hwmod_ocp_if *omap44xx_l3_instr_slaves[] = {
static struct omap_hwmod omap44xx_l3_instr_hwmod = {
.name = "l3_instr",
.class = &omap44xx_l3_hwmod_class,
+ .clkdm_name = "l3_instr_clkdm",
.slaves = omap44xx_l3_instr_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_instr_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -301,6 +304,7 @@ static struct omap_hwmod_irq_info omap44xx_l3_main_1_irqs[] = {
static struct omap_hwmod omap44xx_l3_main_1_hwmod = {
.name = "l3_main_1",
.class = &omap44xx_l3_hwmod_class,
+ .clkdm_name = "l3_1_clkdm",
.slaves = omap44xx_l3_main_1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_1_slaves),
.mpu_irqs = omap44xx_l3_main_1_irqs,
@@ -398,6 +402,7 @@ static struct omap_hwmod_ocp_if *omap44xx_l3_main_2_slaves[] = {
static struct omap_hwmod omap44xx_l3_main_2_hwmod = {
.name = "l3_main_2",
.class = &omap44xx_l3_hwmod_class,
+ .clkdm_name = "l3_2_clkdm",
.slaves = omap44xx_l3_main_2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_2_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -448,6 +453,7 @@ static struct omap_hwmod_ocp_if *omap44xx_l3_main_3_slaves[] = {
static struct omap_hwmod omap44xx_l3_main_3_hwmod = {
.name = "l3_main_3",
.class = &omap44xx_l3_hwmod_class,
+ .clkdm_name = "l3_instr_clkdm",
.slaves = omap44xx_l3_main_3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_3_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -505,6 +511,7 @@ static struct omap_hwmod_ocp_if *omap44xx_l4_abe_slaves[] = {
static struct omap_hwmod omap44xx_l4_abe_hwmod = {
.name = "l4_abe",
.class = &omap44xx_l4_hwmod_class,
+ .clkdm_name = "abe_clkdm",
.slaves = omap44xx_l4_abe_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_abe_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -527,6 +534,7 @@ static struct omap_hwmod_ocp_if *omap44xx_l4_cfg_slaves[] = {
static struct omap_hwmod omap44xx_l4_cfg_hwmod = {
.name = "l4_cfg",
.class = &omap44xx_l4_hwmod_class,
+ .clkdm_name = "l4_cfg_clkdm",
.slaves = omap44xx_l4_cfg_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_cfg_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -549,6 +557,7 @@ static struct omap_hwmod_ocp_if *omap44xx_l4_per_slaves[] = {
static struct omap_hwmod omap44xx_l4_per_hwmod = {
.name = "l4_per",
.class = &omap44xx_l4_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.slaves = omap44xx_l4_per_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_per_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -571,6 +580,7 @@ static struct omap_hwmod_ocp_if *omap44xx_l4_wkup_slaves[] = {
static struct omap_hwmod omap44xx_l4_wkup_hwmod = {
.name = "l4_wkup",
.class = &omap44xx_l4_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
.slaves = omap44xx_l4_wkup_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_wkup_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -601,6 +611,7 @@ static struct omap_hwmod_ocp_if *omap44xx_mpu_private_slaves[] = {
static struct omap_hwmod omap44xx_mpu_private_hwmod = {
.name = "mpu_private",
.class = &omap44xx_mpu_bus_hwmod_class,
+ .clkdm_name = "mpu_clkdm",
.slaves = omap44xx_mpu_private_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mpu_private_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -737,6 +748,7 @@ static struct omap_hwmod_ocp_if *omap44xx_aess_slaves[] = {
static struct omap_hwmod omap44xx_aess_hwmod = {
.name = "aess",
.class = &omap44xx_aess_hwmod_class,
+ .clkdm_name = "abe_clkdm",
.mpu_irqs = omap44xx_aess_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_aess_irqs),
.sdma_reqs = omap44xx_aess_sdma_reqs,
@@ -771,6 +783,7 @@ static struct omap_hwmod_opt_clk bandgap_opt_clks[] = {
static struct omap_hwmod omap44xx_bandgap_hwmod = {
.name = "bandgap",
.class = &omap44xx_bandgap_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
.prcm = {
.omap4 = {
.clkctrl_reg = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
@@ -828,6 +841,7 @@ static struct omap_hwmod_ocp_if *omap44xx_counter_32k_slaves[] = {
static struct omap_hwmod omap44xx_counter_32k_hwmod = {
.name = "counter_32k",
.class = &omap44xx_counter_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
.flags = HWMOD_SWSUP_SIDLE,
.main_clk = "sys_32k_ck",
.prcm = {
@@ -910,6 +924,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dma_system_slaves[] = {
static struct omap_hwmod omap44xx_dma_system_hwmod = {
.name = "dma_system",
.class = &omap44xx_dma_hwmod_class,
+ .clkdm_name = "l3_dma_clkdm",
.mpu_irqs = omap44xx_dma_system_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dma_system_irqs),
.main_clk = "l3_div_ck",
@@ -1001,6 +1016,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dmic_slaves[] = {
static struct omap_hwmod omap44xx_dmic_hwmod = {
.name = "dmic",
.class = &omap44xx_dmic_hwmod_class,
+ .clkdm_name = "abe_clkdm",
.mpu_irqs = omap44xx_dmic_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dmic_irqs),
.sdma_reqs = omap44xx_dmic_sdma_reqs,
@@ -1069,6 +1085,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dsp_slaves[] = {
static struct omap_hwmod omap44xx_dsp_c0_hwmod = {
.name = "dsp_c0",
.class = &omap44xx_dsp_hwmod_class,
+ .clkdm_name = "tesla_clkdm",
.flags = HWMOD_INIT_NO_RESET,
.rst_lines = omap44xx_dsp_c0_resets,
.rst_lines_cnt = ARRAY_SIZE(omap44xx_dsp_c0_resets),
@@ -1083,6 +1100,7 @@ static struct omap_hwmod omap44xx_dsp_c0_hwmod = {
static struct omap_hwmod omap44xx_dsp_hwmod = {
.name = "dsp",
.class = &omap44xx_dsp_hwmod_class,
+ .clkdm_name = "tesla_clkdm",
.mpu_irqs = omap44xx_dsp_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dsp_irqs),
.rst_lines = omap44xx_dsp_resets,
@@ -1175,6 +1193,7 @@ static struct omap_hwmod_opt_clk dss_opt_clks[] = {
static struct omap_hwmod omap44xx_dss_hwmod = {
.name = "dss_core",
.class = &omap44xx_dss_hwmod_class,
+ .clkdm_name = "l3_dss_clkdm",
.main_clk = "dss_fck",
.prcm = {
.omap4 = {
@@ -1268,6 +1287,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_dispc_slaves[] = {
static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
.name = "dss_dispc",
.class = &omap44xx_dispc_hwmod_class,
+ .clkdm_name = "l3_dss_clkdm",
.mpu_irqs = omap44xx_dss_dispc_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dispc_irqs),
.sdma_reqs = omap44xx_dss_dispc_sdma_reqs,
@@ -1359,6 +1379,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_dsi1_slaves[] = {
static struct omap_hwmod omap44xx_dss_dsi1_hwmod = {
.name = "dss_dsi1",
.class = &omap44xx_dsi_hwmod_class,
+ .clkdm_name = "l3_dss_clkdm",
.mpu_irqs = omap44xx_dss_dsi1_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_irqs),
.sdma_reqs = omap44xx_dss_dsi1_sdma_reqs,
@@ -1429,6 +1450,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_dsi2_slaves[] = {
static struct omap_hwmod omap44xx_dss_dsi2_hwmod = {
.name = "dss_dsi2",
.class = &omap44xx_dsi_hwmod_class,
+ .clkdm_name = "l3_dss_clkdm",
.mpu_irqs = omap44xx_dss_dsi2_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_irqs),
.sdma_reqs = omap44xx_dss_dsi2_sdma_reqs,
@@ -1519,6 +1541,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_hdmi_slaves[] = {
static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
.name = "dss_hdmi",
.class = &omap44xx_hdmi_hwmod_class,
+ .clkdm_name = "l3_dss_clkdm",
.mpu_irqs = omap44xx_dss_hdmi_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_irqs),
.sdma_reqs = omap44xx_dss_hdmi_sdma_reqs,
@@ -1605,6 +1628,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_rfbi_slaves[] = {
static struct omap_hwmod omap44xx_dss_rfbi_hwmod = {
.name = "dss_rfbi",
.class = &omap44xx_rfbi_hwmod_class,
+ .clkdm_name = "l3_dss_clkdm",
.sdma_reqs = omap44xx_dss_rfbi_sdma_reqs,
.sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_sdma_reqs),
.main_clk = "dss_fck",
@@ -1674,6 +1698,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_venc_slaves[] = {
static struct omap_hwmod omap44xx_dss_venc_hwmod = {
.name = "dss_venc",
.class = &omap44xx_venc_hwmod_class,
+ .clkdm_name = "l3_dss_clkdm",
.main_clk = "dss_fck",
.prcm = {
.omap4 = {
@@ -1750,6 +1775,7 @@ static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
static struct omap_hwmod omap44xx_gpio1_hwmod = {
.name = "gpio1",
.class = &omap44xx_gpio_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
.mpu_irqs = omap44xx_gpio1_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio1_irqs),
.main_clk = "gpio1_ick",
@@ -1802,6 +1828,7 @@ static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
static struct omap_hwmod omap44xx_gpio2_hwmod = {
.name = "gpio2",
.class = &omap44xx_gpio_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
.mpu_irqs = omap44xx_gpio2_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio2_irqs),
@@ -1855,6 +1882,7 @@ static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
static struct omap_hwmod omap44xx_gpio3_hwmod = {
.name = "gpio3",
.class = &omap44xx_gpio_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
.mpu_irqs = omap44xx_gpio3_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio3_irqs),
@@ -1908,6 +1936,7 @@ static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
static struct omap_hwmod omap44xx_gpio4_hwmod = {
.name = "gpio4",
.class = &omap44xx_gpio_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
.mpu_irqs = omap44xx_gpio4_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio4_irqs),
@@ -1961,6 +1990,7 @@ static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
static struct omap_hwmod omap44xx_gpio5_hwmod = {
.name = "gpio5",
.class = &omap44xx_gpio_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
.mpu_irqs = omap44xx_gpio5_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio5_irqs),
@@ -2014,6 +2044,7 @@ static struct omap_hwmod_opt_clk gpio6_opt_clks[] = {
static struct omap_hwmod omap44xx_gpio6_hwmod = {
.name = "gpio6",
.class = &omap44xx_gpio_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
.mpu_irqs = omap44xx_gpio6_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio6_irqs),
@@ -2093,6 +2124,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hsi_slaves[] = {
static struct omap_hwmod omap44xx_hsi_hwmod = {
.name = "hsi",
.class = &omap44xx_hsi_hwmod_class,
+ .clkdm_name = "l3_init_clkdm",
.mpu_irqs = omap44xx_hsi_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_hsi_irqs),
.main_clk = "hsi_fck",
@@ -2166,6 +2198,7 @@ static struct omap_hwmod_ocp_if *omap44xx_i2c1_slaves[] = {
static struct omap_hwmod omap44xx_i2c1_hwmod = {
.name = "i2c1",
.class = &omap44xx_i2c_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.flags = HWMOD_INIT_NO_RESET,
.mpu_irqs = omap44xx_i2c1_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c1_irqs),
@@ -2219,6 +2252,7 @@ static struct omap_hwmod_ocp_if *omap44xx_i2c2_slaves[] = {
static struct omap_hwmod omap44xx_i2c2_hwmod = {
.name = "i2c2",
.class = &omap44xx_i2c_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.flags = HWMOD_INIT_NO_RESET,
.mpu_irqs = omap44xx_i2c2_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c2_irqs),
@@ -2272,6 +2306,7 @@ static struct omap_hwmod_ocp_if *omap44xx_i2c3_slaves[] = {
static struct omap_hwmod omap44xx_i2c3_hwmod = {
.name = "i2c3",
.class = &omap44xx_i2c_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.flags = HWMOD_INIT_NO_RESET,
.mpu_irqs = omap44xx_i2c3_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c3_irqs),
@@ -2325,6 +2360,7 @@ static struct omap_hwmod_ocp_if *omap44xx_i2c4_slaves[] = {
static struct omap_hwmod omap44xx_i2c4_hwmod = {
.name = "i2c4",
.class = &omap44xx_i2c_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.flags = HWMOD_INIT_NO_RESET,
.mpu_irqs = omap44xx_i2c4_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c4_irqs),
@@ -2389,6 +2425,7 @@ static struct omap_hwmod_ocp_if *omap44xx_ipu_slaves[] = {
static struct omap_hwmod omap44xx_ipu_c0_hwmod = {
.name = "ipu_c0",
.class = &omap44xx_ipu_hwmod_class,
+ .clkdm_name = "ducati_clkdm",
.flags = HWMOD_INIT_NO_RESET,
.rst_lines = omap44xx_ipu_c0_resets,
.rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_c0_resets),
@@ -2404,6 +2441,7 @@ static struct omap_hwmod omap44xx_ipu_c0_hwmod = {
static struct omap_hwmod omap44xx_ipu_c1_hwmod = {
.name = "ipu_c1",
.class = &omap44xx_ipu_hwmod_class,
+ .clkdm_name = "ducati_clkdm",
.flags = HWMOD_INIT_NO_RESET,
.rst_lines = omap44xx_ipu_c1_resets,
.rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_c1_resets),
@@ -2418,6 +2456,7 @@ static struct omap_hwmod omap44xx_ipu_c1_hwmod = {
static struct omap_hwmod omap44xx_ipu_hwmod = {
.name = "ipu",
.class = &omap44xx_ipu_hwmod_class,
+ .clkdm_name = "ducati_clkdm",
.mpu_irqs = omap44xx_ipu_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_ipu_irqs),
.rst_lines = omap44xx_ipu_resets,
@@ -2504,6 +2543,7 @@ static struct omap_hwmod_opt_clk iss_opt_clks[] = {
static struct omap_hwmod omap44xx_iss_hwmod = {
.name = "iss",
.class = &omap44xx_iss_hwmod_class,
+ .clkdm_name = "iss_clkdm",
.mpu_irqs = omap44xx_iss_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_iss_irqs),
.sdma_reqs = omap44xx_iss_sdma_reqs,
@@ -2585,6 +2625,7 @@ static struct omap_hwmod_ocp_if *omap44xx_iva_slaves[] = {
static struct omap_hwmod omap44xx_iva_seq0_hwmod = {
.name = "iva_seq0",
.class = &omap44xx_iva_hwmod_class,
+ .clkdm_name = "ivahd_clkdm",
.flags = HWMOD_INIT_NO_RESET,
.rst_lines = omap44xx_iva_seq0_resets,
.rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_seq0_resets),
@@ -2600,6 +2641,7 @@ static struct omap_hwmod omap44xx_iva_seq0_hwmod = {
static struct omap_hwmod omap44xx_iva_seq1_hwmod = {
.name = "iva_seq1",
.class = &omap44xx_iva_hwmod_class,
+ .clkdm_name = "ivahd_clkdm",
.flags = HWMOD_INIT_NO_RESET,
.rst_lines = omap44xx_iva_seq1_resets,
.rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_seq1_resets),
@@ -2614,6 +2656,7 @@ static struct omap_hwmod omap44xx_iva_seq1_hwmod = {
static struct omap_hwmod omap44xx_iva_hwmod = {
.name = "iva",
.class = &omap44xx_iva_hwmod_class,
+ .clkdm_name = "ivahd_clkdm",
.mpu_irqs = omap44xx_iva_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_iva_irqs),
.rst_lines = omap44xx_iva_resets,
@@ -2686,6 +2729,7 @@ static struct omap_hwmod_ocp_if *omap44xx_kbd_slaves[] = {
static struct omap_hwmod omap44xx_kbd_hwmod = {
.name = "kbd",
.class = &omap44xx_kbd_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
.mpu_irqs = omap44xx_kbd_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_kbd_irqs),
.main_clk = "kbd_fck",
@@ -2751,6 +2795,7 @@ static struct omap_hwmod_ocp_if *omap44xx_mailbox_slaves[] = {
static struct omap_hwmod omap44xx_mailbox_hwmod = {
.name = "mailbox",
.class = &omap44xx_mailbox_hwmod_class,
+ .clkdm_name = "l4_cfg_clkdm",
.mpu_irqs = omap44xx_mailbox_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mailbox_irqs),
.prcm = {
@@ -2840,6 +2885,7 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp1_slaves[] = {
static struct omap_hwmod omap44xx_mcbsp1_hwmod = {
.name = "mcbsp1",
.class = &omap44xx_mcbsp_hwmod_class,
+ .clkdm_name = "abe_clkdm",
.mpu_irqs = omap44xx_mcbsp1_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcbsp1_irqs),
.sdma_reqs = omap44xx_mcbsp1_sdma_reqs,
@@ -2913,6 +2959,7 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp2_slaves[] = {
static struct omap_hwmod omap44xx_mcbsp2_hwmod = {
.name = "mcbsp2",
.class = &omap44xx_mcbsp_hwmod_class,
+ .clkdm_name = "abe_clkdm",
.mpu_irqs = omap44xx_mcbsp2_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcbsp2_irqs),
.sdma_reqs = omap44xx_mcbsp2_sdma_reqs,
@@ -2986,6 +3033,7 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp3_slaves[] = {
static struct omap_hwmod omap44xx_mcbsp3_hwmod = {
.name = "mcbsp3",
.class = &omap44xx_mcbsp_hwmod_class,
+ .clkdm_name = "abe_clkdm",
.mpu_irqs = omap44xx_mcbsp3_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcbsp3_irqs),
.sdma_reqs = omap44xx_mcbsp3_sdma_reqs,
@@ -3038,6 +3086,7 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp4_slaves[] = {
static struct omap_hwmod omap44xx_mcbsp4_hwmod = {
.name = "mcbsp4",
.class = &omap44xx_mcbsp_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_mcbsp4_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcbsp4_irqs),
.sdma_reqs = omap44xx_mcbsp4_sdma_reqs,
@@ -3130,6 +3179,7 @@ static struct omap_hwmod_ocp_if *omap44xx_mcpdm_slaves[] = {
static struct omap_hwmod omap44xx_mcpdm_hwmod = {
.name = "mcpdm",
.class = &omap44xx_mcpdm_hwmod_class,
+ .clkdm_name = "abe_clkdm",
.mpu_irqs = omap44xx_mcpdm_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcpdm_irqs),
.sdma_reqs = omap44xx_mcpdm_sdma_reqs,
@@ -3215,6 +3265,7 @@ static struct omap2_mcspi_dev_attr mcspi1_dev_attr = {
static struct omap_hwmod omap44xx_mcspi1_hwmod = {
.name = "mcspi1",
.class = &omap44xx_mcspi_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_mcspi1_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcspi1_irqs),
.sdma_reqs = omap44xx_mcspi1_sdma_reqs,
@@ -3275,6 +3326,7 @@ static struct omap2_mcspi_dev_attr mcspi2_dev_attr = {
static struct omap_hwmod omap44xx_mcspi2_hwmod = {
.name = "mcspi2",
.class = &omap44xx_mcspi_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_mcspi2_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcspi2_irqs),
.sdma_reqs = omap44xx_mcspi2_sdma_reqs,
@@ -3335,6 +3387,7 @@ static struct omap2_mcspi_dev_attr mcspi3_dev_attr = {
static struct omap_hwmod omap44xx_mcspi3_hwmod = {
.name = "mcspi3",
.class = &omap44xx_mcspi_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_mcspi3_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcspi3_irqs),
.sdma_reqs = omap44xx_mcspi3_sdma_reqs,
@@ -3393,6 +3446,7 @@ static struct omap2_mcspi_dev_attr mcspi4_dev_attr = {
static struct omap_hwmod omap44xx_mcspi4_hwmod = {
.name = "mcspi4",
.class = &omap44xx_mcspi_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_mcspi4_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcspi4_irqs),
.sdma_reqs = omap44xx_mcspi4_sdma_reqs,
@@ -3477,6 +3531,7 @@ static struct omap_mmc_dev_attr mmc1_dev_attr = {
static struct omap_hwmod omap44xx_mmc1_hwmod = {
.name = "mmc1",
.class = &omap44xx_mmc_hwmod_class,
+ .clkdm_name = "l3_init_clkdm",
.mpu_irqs = omap44xx_mmc1_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mmc1_irqs),
.sdma_reqs = omap44xx_mmc1_sdma_reqs,
@@ -3536,6 +3591,7 @@ static struct omap_hwmod_ocp_if *omap44xx_mmc2_slaves[] = {
static struct omap_hwmod omap44xx_mmc2_hwmod = {
.name = "mmc2",
.class = &omap44xx_mmc_hwmod_class,
+ .clkdm_name = "l3_init_clkdm",
.mpu_irqs = omap44xx_mmc2_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mmc2_irqs),
.sdma_reqs = omap44xx_mmc2_sdma_reqs,
@@ -3590,6 +3646,7 @@ static struct omap_hwmod_ocp_if *omap44xx_mmc3_slaves[] = {
static struct omap_hwmod omap44xx_mmc3_hwmod = {
.name = "mmc3",
.class = &omap44xx_mmc_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_mmc3_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mmc3_irqs),
.sdma_reqs = omap44xx_mmc3_sdma_reqs,
@@ -3642,6 +3699,7 @@ static struct omap_hwmod_ocp_if *omap44xx_mmc4_slaves[] = {
static struct omap_hwmod omap44xx_mmc4_hwmod = {
.name = "mmc4",
.class = &omap44xx_mmc_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_mmc4_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mmc4_irqs),
.sdma_reqs = omap44xx_mmc4_sdma_reqs,
@@ -3694,6 +3752,7 @@ static struct omap_hwmod_ocp_if *omap44xx_mmc5_slaves[] = {
static struct omap_hwmod omap44xx_mmc5_hwmod = {
.name = "mmc5",
.class = &omap44xx_mmc_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_mmc5_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mmc5_irqs),
.sdma_reqs = omap44xx_mmc5_sdma_reqs,
@@ -3735,6 +3794,7 @@ static struct omap_hwmod_ocp_if *omap44xx_mpu_masters[] = {
static struct omap_hwmod omap44xx_mpu_hwmod = {
.name = "mpu",
.class = &omap44xx_mpu_hwmod_class,
+ .clkdm_name = "mpu_clkdm",
.flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
.mpu_irqs = omap44xx_mpu_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mpu_irqs),
@@ -3807,6 +3867,7 @@ static struct omap_hwmod_ocp_if *omap44xx_smartreflex_core_slaves[] = {
static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
.name = "smartreflex_core",
.class = &omap44xx_smartreflex_hwmod_class,
+ .clkdm_name = "l4_ao_clkdm",
.mpu_irqs = omap44xx_smartreflex_core_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_irqs),
.main_clk = "smartreflex_core_fck",
@@ -3853,6 +3914,7 @@ static struct omap_hwmod_ocp_if *omap44xx_smartreflex_iva_slaves[] = {
static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
.name = "smartreflex_iva",
.class = &omap44xx_smartreflex_hwmod_class,
+ .clkdm_name = "l4_ao_clkdm",
.mpu_irqs = omap44xx_smartreflex_iva_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_irqs),
.main_clk = "smartreflex_iva_fck",
@@ -3899,6 +3961,7 @@ static struct omap_hwmod_ocp_if *omap44xx_smartreflex_mpu_slaves[] = {
static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
.name = "smartreflex_mpu",
.class = &omap44xx_smartreflex_hwmod_class,
+ .clkdm_name = "l4_ao_clkdm",
.mpu_irqs = omap44xx_smartreflex_mpu_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_irqs),
.main_clk = "smartreflex_mpu_fck",
@@ -3964,6 +4027,7 @@ static struct omap_hwmod_ocp_if *omap44xx_spinlock_slaves[] = {
static struct omap_hwmod omap44xx_spinlock_hwmod = {
.name = "spinlock",
.class = &omap44xx_spinlock_hwmod_class,
+ .clkdm_name = "l4_cfg_clkdm",
.prcm = {
.omap4 = {
.clkctrl_reg = OMAP4430_CM_L4CFG_HW_SEM_CLKCTRL,
@@ -4044,6 +4108,7 @@ static struct omap_hwmod_ocp_if *omap44xx_timer1_slaves[] = {
static struct omap_hwmod omap44xx_timer1_hwmod = {
.name = "timer1",
.class = &omap44xx_timer_1ms_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
.mpu_irqs = omap44xx_timer1_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer1_irqs),
.main_clk = "timer1_fck",
@@ -4089,6 +4154,7 @@ static struct omap_hwmod_ocp_if *omap44xx_timer2_slaves[] = {
static struct omap_hwmod omap44xx_timer2_hwmod = {
.name = "timer2",
.class = &omap44xx_timer_1ms_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_timer2_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer2_irqs),
.main_clk = "timer2_fck",
@@ -4134,6 +4200,7 @@ static struct omap_hwmod_ocp_if *omap44xx_timer3_slaves[] = {
static struct omap_hwmod omap44xx_timer3_hwmod = {
.name = "timer3",
.class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_timer3_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer3_irqs),
.main_clk = "timer3_fck",
@@ -4179,6 +4246,7 @@ static struct omap_hwmod_ocp_if *omap44xx_timer4_slaves[] = {
static struct omap_hwmod omap44xx_timer4_hwmod = {
.name = "timer4",
.class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_timer4_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer4_irqs),
.main_clk = "timer4_fck",
@@ -4243,6 +4311,7 @@ static struct omap_hwmod_ocp_if *omap44xx_timer5_slaves[] = {
static struct omap_hwmod omap44xx_timer5_hwmod = {
.name = "timer5",
.class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "abe_clkdm",
.mpu_irqs = omap44xx_timer5_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer5_irqs),
.main_clk = "timer5_fck",
@@ -4307,6 +4376,7 @@ static struct omap_hwmod_ocp_if *omap44xx_timer6_slaves[] = {
static struct omap_hwmod omap44xx_timer6_hwmod = {
.name = "timer6",
.class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "abe_clkdm",
.mpu_irqs = omap44xx_timer6_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer6_irqs),
.main_clk = "timer6_fck",
@@ -4371,6 +4441,7 @@ static struct omap_hwmod_ocp_if *omap44xx_timer7_slaves[] = {
static struct omap_hwmod omap44xx_timer7_hwmod = {
.name = "timer7",
.class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "abe_clkdm",
.mpu_irqs = omap44xx_timer7_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer7_irqs),
.main_clk = "timer7_fck",
@@ -4435,6 +4506,7 @@ static struct omap_hwmod_ocp_if *omap44xx_timer8_slaves[] = {
static struct omap_hwmod omap44xx_timer8_hwmod = {
.name = "timer8",
.class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "abe_clkdm",
.mpu_irqs = omap44xx_timer8_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer8_irqs),
.main_clk = "timer8_fck",
@@ -4480,6 +4552,7 @@ static struct omap_hwmod_ocp_if *omap44xx_timer9_slaves[] = {
static struct omap_hwmod omap44xx_timer9_hwmod = {
.name = "timer9",
.class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_timer9_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer9_irqs),
.main_clk = "timer9_fck",
@@ -4525,6 +4598,7 @@ static struct omap_hwmod_ocp_if *omap44xx_timer10_slaves[] = {
static struct omap_hwmod omap44xx_timer10_hwmod = {
.name = "timer10",
.class = &omap44xx_timer_1ms_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_timer10_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer10_irqs),
.main_clk = "timer10_fck",
@@ -4570,6 +4644,7 @@ static struct omap_hwmod_ocp_if *omap44xx_timer11_slaves[] = {
static struct omap_hwmod omap44xx_timer11_hwmod = {
.name = "timer11",
.class = &omap44xx_timer_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_timer11_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer11_irqs),
.main_clk = "timer11_fck",
@@ -4642,6 +4717,7 @@ static struct omap_hwmod_ocp_if *omap44xx_uart1_slaves[] = {
static struct omap_hwmod omap44xx_uart1_hwmod = {
.name = "uart1",
.class = &omap44xx_uart_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_uart1_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_uart1_irqs),
.sdma_reqs = omap44xx_uart1_sdma_reqs,
@@ -4694,6 +4770,7 @@ static struct omap_hwmod_ocp_if *omap44xx_uart2_slaves[] = {
static struct omap_hwmod omap44xx_uart2_hwmod = {
.name = "uart2",
.class = &omap44xx_uart_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_uart2_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_uart2_irqs),
.sdma_reqs = omap44xx_uart2_sdma_reqs,
@@ -4746,6 +4823,7 @@ static struct omap_hwmod_ocp_if *omap44xx_uart3_slaves[] = {
static struct omap_hwmod omap44xx_uart3_hwmod = {
.name = "uart3",
.class = &omap44xx_uart_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
.mpu_irqs = omap44xx_uart3_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_uart3_irqs),
@@ -4799,6 +4877,7 @@ static struct omap_hwmod_ocp_if *omap44xx_uart4_slaves[] = {
static struct omap_hwmod omap44xx_uart4_hwmod = {
.name = "uart4",
.class = &omap44xx_uart_hwmod_class,
+ .clkdm_name = "l4_per_clkdm",
.mpu_irqs = omap44xx_uart4_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_uart4_irqs),
.sdma_reqs = omap44xx_uart4_sdma_reqs,
@@ -4878,6 +4957,7 @@ static struct omap_hwmod_opt_clk usb_otg_hs_opt_clks[] = {
static struct omap_hwmod omap44xx_usb_otg_hs_hwmod = {
.name = "usb_otg_hs",
.class = &omap44xx_usb_otg_hs_hwmod_class,
+ .clkdm_name = "l3_init_clkdm",
.flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
.mpu_irqs = omap44xx_usb_otg_hs_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_usb_otg_hs_irqs),
@@ -4951,6 +5031,7 @@ static struct omap_hwmod_ocp_if *omap44xx_wd_timer2_slaves[] = {
static struct omap_hwmod omap44xx_wd_timer2_hwmod = {
.name = "wd_timer2",
.class = &omap44xx_wd_timer_hwmod_class,
+ .clkdm_name = "l4_wkup_clkdm",
.mpu_irqs = omap44xx_wd_timer2_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_wd_timer2_irqs),
.main_clk = "wd_timer2_fck",
@@ -5015,6 +5096,7 @@ static struct omap_hwmod_ocp_if *omap44xx_wd_timer3_slaves[] = {
static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
.name = "wd_timer3",
.class = &omap44xx_wd_timer_hwmod_class,
+ .clkdm_name = "abe_clkdm",
.mpu_irqs = omap44xx_wd_timer3_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_wd_timer3_irqs),
.main_clk = "wd_timer3_fck",
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index e93438c..5d77c5b 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -519,6 +519,7 @@ struct omap_hwmod {
const char *main_clk;
struct clk *_clk;
struct omap_hwmod_opt_clk *opt_clks;
+ char *clkdm_name;
char *vdd_name;
struct voltagedomain *voltdm;
struct omap_hwmod_ocp_if **masters; /* connect to *_IA */
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-06-24 11:05:48 UTC
Permalink
At boot time, lookup the clkdm_name to get the clkdm
structure pointer for further usage.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Cc: Paul Walmsley <***@pwsan.com>
Cc: Rajendra Nayak <***@ti.com>
---
arch/arm/mach-omap2/omap_hwmod.c | 34 +++++++++++++++++++++++++-
arch/arm/plat-omap/include/plat/omap_hwmod.h | 1 +
2 files changed, 34 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 55ad6a5..bb63e2d 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -919,9 +919,40 @@ static struct omap_hwmod *_lookup(const char *name)

return oh;
}
+/**
+ * _init_clkdm - look up a clockdomain name, store pointer in omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Convert a clockdomain name stored in a struct omap_hwmod into a
+ * clockdomain pointer, and save it into the struct omap_hwmod.
+ * return -EINVAL if clkdm_name does not exist or if the lookup failed.
+ */
+static int _init_clkdm(struct omap_hwmod *oh)
+{
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ return 0;
+
+ if (!oh->clkdm_name) {
+ pr_warning("omap_hwmod: %s: no clkdm_name\n", oh->name);
+ return -EINVAL;
+ }
+
+ oh->clkdm = clkdm_lookup(oh->clkdm_name);
+ if (!oh->clkdm) {
+ pr_warning("omap_hwmod: %s: could not associate to clkdm %s\n",
+ oh->name, oh->clkdm_name);
+ return -EINVAL;
+ }
+
+ pr_debug("omap_hwmod: %s: associated to clkdm %s\n",
+ oh->name, oh->clkdm_name);
+
+ return 0;
+}

/**
- * _init_clocks - clk_get() all clocks associated with this hwmod
+ * _init_clocks - clk_get() all clocks associated with this hwmod. Retrieve as
+ * well the clockdomain.
* @oh: struct omap_hwmod *
* @data: not used; pass NULL
*
@@ -941,6 +972,7 @@ static int _init_clocks(struct omap_hwmod *oh, void *data)
ret |= _init_main_clk(oh);
ret |= _init_interface_clks(oh);
ret |= _init_opt_clks(oh);
+ ret |= _init_clkdm(oh);

if (!ret)
oh->_state = _HWMOD_STATE_CLKS_INITED;
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 5d77c5b..28ea1c8 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -520,6 +520,7 @@ struct omap_hwmod {
struct clk *_clk;
struct omap_hwmod_opt_clk *opt_clks;
char *clkdm_name;
+ struct clockdomain *clkdm;
char *vdd_name;
struct voltagedomain *voltdm;
struct omap_hwmod_ocp_if **masters; /* connect to *_IA */
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-06-24 11:05:51 UTC
Permalink
Since the clkdm is now part of the omap_hwmod structure, there is no need
to retrieve it from the main_clock or interface clock.
The code can be simplified a little bit with a direct access.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Cc: Paul Walmsley <***@pwsan.com>
Cc: Rajendra Nayak <***@ti.com>
---
arch/arm/mach-omap2/omap_hwmod.c | 34 ++++++++--------------------------
1 files changed, 8 insertions(+), 26 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 617ad21..8ac2546 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -463,13 +463,13 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
*/
static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
{
- if (!oh->_clk)
+ if (!oh->clkdm)
return -EINVAL;

- if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS)
+ if (oh->clkdm->flags & CLKDM_NO_AUTODEPS)
return 0;

- return clkdm_add_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
+ return clkdm_add_sleepdep(oh->clkdm, init_oh->clkdm);
}

/**
@@ -487,13 +487,13 @@ static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
*/
static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
{
- if (!oh->_clk)
+ if (!oh->clkdm)
return -EINVAL;

- if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS)
+ if (oh->clkdm->flags & CLKDM_NO_AUTODEPS)
return 0;

- return clkdm_del_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
+ return clkdm_del_sleepdep(oh->clkdm, init_oh->clkdm);
}

/**
@@ -518,10 +518,6 @@ static int _init_main_clk(struct omap_hwmod *oh)
return -EINVAL;
}

- if (!oh->_clk->clkdm)
- pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n",
- oh->main_clk, oh->_clk->name);
-
return ret;
}

@@ -2104,24 +2100,10 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res)
*/
struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
{
- struct clk *c;
-
- if (!oh)
+ if (!oh || !oh->clkdm)
return NULL;

- if (oh->_clk) {
- c = oh->_clk;
- } else {
- if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
- return NULL;
- c = oh->slaves[oh->_mpu_port_index]->_clk;
- }
-
- if (!c->clkdm)
- return NULL;
-
- return c->clkdm->pwrdm.ptr;
-
+ return oh->clkdm->pwrdm.ptr;
}

/**
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-06-24 11:05:49 UTC
Permalink
The CLKCTRL register was accessed using an absolute address.
The usage of hardcoded macros to calculate virtual address from physical
one should be avoided as much as possible.
The usage of a offset will allow future improvement like migration from
the current architecture code toward a module driver.

Update cm_xxx accessor, move definition to the proper header file and
update copyrights.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Cc: Paul Walmsley <***@pwsan.com>
Cc: Rajendra Nayak <***@ti.com>
---
arch/arm/mach-omap2/cm44xx.h | 3 +-
arch/arm/mach-omap2/cminst44xx.c | 24 +++-
arch/arm/mach-omap2/cminst44xx.h | 4 +-
arch/arm/mach-omap2/omap_hwmod.c | 10 +-
arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 182 ++++++++++++++++---------
arch/arm/plat-omap/include/plat/omap_hwmod.h | 2 +-
6 files changed, 144 insertions(+), 81 deletions(-)

diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h
index 0b87ec8..cdda756 100644
--- a/arch/arm/mach-omap2/cm44xx.h
+++ b/arch/arm/mach-omap2/cm44xx.h
@@ -1,7 +1,7 @@
/*
* OMAP4 Clock Management (CM) definitions
*
- * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2011 Texas Instruments, Inc.
* Copyright (C) 2007-2009 Nokia Corporation
*
* Written by Paul Walmsley
@@ -26,7 +26,6 @@
/* Function prototypes */
# ifndef __ASSEMBLER__

-extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg);

# endif
#endif
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
index a482bfa..6fa0ebb 100644
--- a/arch/arm/mach-omap2/cminst44xx.c
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -2,6 +2,7 @@
* OMAP4 CM instance functions
*
* Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2011 Texas Instruments, Inc.
* Paul Walmsley
*
* This program is free software; you can redistribute it and/or modify
@@ -199,9 +200,20 @@ void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs)
*
*/

+static u32 _clkctrl_idlest(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs)
+{
+ u32 v = omap4_cminst_read_inst_reg(part, inst, cdoffs + clkctrl_offs);
+ v &= OMAP4430_IDLEST_MASK;
+ v >>= OMAP4430_IDLEST_SHIFT;
+ return v;
+}
+
/**
* omap4_cm_wait_module_ready - wait for a module to be in 'func' state
- * @clkctrl_reg: CLKCTRL module address
+ * @part: PRCM partition ID that the CM_CLKCTRL register exists in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
*
* Wait for the module IDLEST to be functional. If the idle state is in any
* the non functional state (trans, idle or disabled), module and thus the
@@ -217,17 +229,13 @@ void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs)
* 0x3 disabled: Module is disabled and cannot be accessed
*
*/
-int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg)
+int omap4_cm_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs)
{
int i = 0;

- if (!clkctrl_reg)
- return 0;
-
omap_test_timeout((
- ((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) == 0) ||
- (((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) >>
- OMAP4430_IDLEST_SHIFT) == 0x2)),
+ _clkctrl_idlest(part, inst, cdoffs, clkctrl_offs) == 0 ||
+ _clkctrl_idlest(part, inst, cdoffs, clkctrl_offs) == 0x2),
MAX_MODULE_READY_TIME, i);

return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
diff --git a/arch/arm/mach-omap2/cminst44xx.h b/arch/arm/mach-omap2/cminst44xx.h
index 2b32c18..9d39c70 100644
--- a/arch/arm/mach-omap2/cminst44xx.h
+++ b/arch/arm/mach-omap2/cminst44xx.h
@@ -17,6 +17,8 @@ extern void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs);
extern void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs);
extern void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs);

+extern int omap4_cm_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs);
+
/*
* In an ideal world, we would not export these low-level functions,
* but this will probably take some time to fix properly
@@ -32,6 +34,4 @@ extern u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst,
extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx,
u32 mask);

-extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg);
-
#endif
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index bb63e2d..ea1c976 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -145,7 +145,7 @@
#include <plat/prcm.h>

#include "cm2xxx_3xxx.h"
-#include "cm44xx.h"
+#include "cminst44xx.h"
#include "prm2xxx_3xxx.h"
#include "prm44xx.h"
#include "mux.h"
@@ -1014,7 +1014,13 @@ static int _wait_target_ready(struct omap_hwmod *oh)
oh->prcm.omap2.idlest_reg_id,
oh->prcm.omap2.idlest_idle_bit);
} else if (cpu_is_omap44xx()) {
- ret = omap4_cm_wait_module_ready(oh->prcm.omap4.clkctrl_reg);
+ if (!oh->clkdm)
+ return -EINVAL;
+
+ ret = omap4_cm_wait_module_ready(oh->clkdm->prcm_partition,
+ oh->clkdm->cm_inst,
+ oh->clkdm->clkdm_offs,
+ oh->prcm.omap4.clkctrl_offs);
} else {
BUG();
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 63ba19f..e4e50a8 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -121,6 +121,11 @@ static struct omap_hwmod omap44xx_dmm_hwmod = {
.name = "dmm",
.class = &omap44xx_dmm_hwmod_class,
.clkdm_name = "l3_emif_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET,
+ },
+ },
.slaves = omap44xx_dmm_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dmm_slaves),
.mpu_irqs = omap44xx_dmm_irqs,
@@ -173,6 +178,11 @@ static struct omap_hwmod omap44xx_emif_fw_hwmod = {
.name = "emif_fw",
.class = &omap44xx_emif_fw_hwmod_class,
.clkdm_name = "l3_emif_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET,
+ },
+ },
.slaves = omap44xx_emif_fw_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_emif_fw_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -213,6 +223,11 @@ static struct omap_hwmod omap44xx_l3_instr_hwmod = {
.name = "l3_instr",
.class = &omap44xx_l3_hwmod_class,
.clkdm_name = "l3_instr_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET,
+ },
+ },
.slaves = omap44xx_l3_instr_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_instr_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -305,6 +320,11 @@ static struct omap_hwmod omap44xx_l3_main_1_hwmod = {
.name = "l3_main_1",
.class = &omap44xx_l3_hwmod_class,
.clkdm_name = "l3_1_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET,
+ },
+ },
.slaves = omap44xx_l3_main_1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_1_slaves),
.mpu_irqs = omap44xx_l3_main_1_irqs,
@@ -403,6 +423,11 @@ static struct omap_hwmod omap44xx_l3_main_2_hwmod = {
.name = "l3_main_2",
.class = &omap44xx_l3_hwmod_class,
.clkdm_name = "l3_2_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET,
+ },
+ },
.slaves = omap44xx_l3_main_2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_2_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -454,6 +479,11 @@ static struct omap_hwmod omap44xx_l3_main_3_hwmod = {
.name = "l3_main_3",
.class = &omap44xx_l3_hwmod_class,
.clkdm_name = "l3_instr_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET,
+ },
+ },
.slaves = omap44xx_l3_main_3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_3_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -512,6 +542,11 @@ static struct omap_hwmod omap44xx_l4_abe_hwmod = {
.name = "l4_abe",
.class = &omap44xx_l4_hwmod_class,
.clkdm_name = "abe_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET,
+ },
+ },
.slaves = omap44xx_l4_abe_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_abe_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -535,6 +570,11 @@ static struct omap_hwmod omap44xx_l4_cfg_hwmod = {
.name = "l4_cfg",
.class = &omap44xx_l4_hwmod_class,
.clkdm_name = "l4_cfg_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET,
+ },
+ },
.slaves = omap44xx_l4_cfg_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_cfg_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -558,6 +598,11 @@ static struct omap_hwmod omap44xx_l4_per_hwmod = {
.name = "l4_per",
.class = &omap44xx_l4_hwmod_class,
.clkdm_name = "l4_per_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET,
+ },
+ },
.slaves = omap44xx_l4_per_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_per_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -581,6 +626,11 @@ static struct omap_hwmod omap44xx_l4_wkup_hwmod = {
.name = "l4_wkup",
.class = &omap44xx_l4_hwmod_class,
.clkdm_name = "l4_wkup_clkdm",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = OMAP4_CM_WKUP_L4WKUP_CLKCTRL_OFFSET,
+ },
+ },
.slaves = omap44xx_l4_wkup_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_wkup_slaves),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -756,7 +806,7 @@ static struct omap_hwmod omap44xx_aess_hwmod = {
.main_clk = "aess_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM1_ABE_AESS_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_aess_slaves,
@@ -786,7 +836,7 @@ static struct omap_hwmod omap44xx_bandgap_hwmod = {
.clkdm_name = "l4_wkup_clkdm",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_WKUP_BANDGAP_CLKCTRL_OFFSET,
},
},
.opt_clks = bandgap_opt_clks,
@@ -846,7 +896,7 @@ static struct omap_hwmod omap44xx_counter_32k_hwmod = {
.main_clk = "sys_32k_ck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_WKUP_SYNCTIMER_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_counter_32k_slaves,
@@ -930,7 +980,7 @@ static struct omap_hwmod omap44xx_dma_system_hwmod = {
.main_clk = "l3_div_ck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_SDMA_SDMA_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET,
},
},
.dev_attr = &dma_dev_attr,
@@ -1024,7 +1074,7 @@ static struct omap_hwmod omap44xx_dmic_hwmod = {
.main_clk = "dmic_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM1_ABE_DMIC_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_dmic_slaves,
@@ -1108,7 +1158,7 @@ static struct omap_hwmod omap44xx_dsp_hwmod = {
.main_clk = "dsp_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_TESLA_TESLA_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET,
.rstctrl_reg = OMAP4430_RM_TESLA_RSTCTRL,
},
},
@@ -1197,7 +1247,7 @@ static struct omap_hwmod omap44xx_dss_hwmod = {
.main_clk = "dss_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
},
},
.opt_clks = dss_opt_clks,
@@ -1295,7 +1345,7 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
.main_clk = "dss_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_dss_dispc_slaves,
@@ -1387,7 +1437,7 @@ static struct omap_hwmod omap44xx_dss_dsi1_hwmod = {
.main_clk = "dss_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_dss_dsi1_slaves,
@@ -1458,7 +1508,7 @@ static struct omap_hwmod omap44xx_dss_dsi2_hwmod = {
.main_clk = "dss_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_dss_dsi2_slaves,
@@ -1549,7 +1599,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
.main_clk = "dss_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_dss_hdmi_slaves,
@@ -1634,7 +1684,7 @@ static struct omap_hwmod omap44xx_dss_rfbi_hwmod = {
.main_clk = "dss_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_dss_rfbi_slaves,
@@ -1702,7 +1752,7 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = {
.main_clk = "dss_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_dss_venc_slaves,
@@ -1781,7 +1831,7 @@ static struct omap_hwmod omap44xx_gpio1_hwmod = {
.main_clk = "gpio1_ick",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET,
},
},
.opt_clks = gpio1_opt_clks,
@@ -1835,7 +1885,7 @@ static struct omap_hwmod omap44xx_gpio2_hwmod = {
.main_clk = "gpio2_ick",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_GPIO2_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET,
},
},
.opt_clks = gpio2_opt_clks,
@@ -1889,7 +1939,7 @@ static struct omap_hwmod omap44xx_gpio3_hwmod = {
.main_clk = "gpio3_ick",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET,
},
},
.opt_clks = gpio3_opt_clks,
@@ -1943,7 +1993,7 @@ static struct omap_hwmod omap44xx_gpio4_hwmod = {
.main_clk = "gpio4_ick",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_GPIO4_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET,
},
},
.opt_clks = gpio4_opt_clks,
@@ -1997,7 +2047,7 @@ static struct omap_hwmod omap44xx_gpio5_hwmod = {
.main_clk = "gpio5_ick",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_GPIO5_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET,
},
},
.opt_clks = gpio5_opt_clks,
@@ -2051,7 +2101,7 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = {
.main_clk = "gpio6_ick",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_GPIO6_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET,
},
},
.opt_clks = gpio6_opt_clks,
@@ -2130,7 +2180,7 @@ static struct omap_hwmod omap44xx_hsi_hwmod = {
.main_clk = "hsi_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L3INIT_HSI_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_hsi_slaves,
@@ -2207,7 +2257,7 @@ static struct omap_hwmod omap44xx_i2c1_hwmod = {
.main_clk = "i2c1_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_I2C1_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_i2c1_slaves,
@@ -2261,7 +2311,7 @@ static struct omap_hwmod omap44xx_i2c2_hwmod = {
.main_clk = "i2c2_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_I2C2_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_i2c2_slaves,
@@ -2315,7 +2365,7 @@ static struct omap_hwmod omap44xx_i2c3_hwmod = {
.main_clk = "i2c3_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_I2C3_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_i2c3_slaves,
@@ -2369,7 +2419,7 @@ static struct omap_hwmod omap44xx_i2c4_hwmod = {
.main_clk = "i2c4_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_I2C4_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_i2c4_slaves,
@@ -2464,7 +2514,7 @@ static struct omap_hwmod omap44xx_ipu_hwmod = {
.main_clk = "ipu_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_DUCATI_DUCATI_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET,
.rstctrl_reg = OMAP4430_RM_DUCATI_RSTCTRL,
},
},
@@ -2551,7 +2601,7 @@ static struct omap_hwmod omap44xx_iss_hwmod = {
.main_clk = "iss_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_CAM_ISS_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET,
},
},
.opt_clks = iss_opt_clks,
@@ -2664,7 +2714,7 @@ static struct omap_hwmod omap44xx_iva_hwmod = {
.main_clk = "iva_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET,
.rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL,
},
},
@@ -2735,7 +2785,7 @@ static struct omap_hwmod omap44xx_kbd_hwmod = {
.main_clk = "kbd_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_kbd_slaves,
@@ -2800,7 +2850,7 @@ static struct omap_hwmod omap44xx_mailbox_hwmod = {
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mailbox_irqs),
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4CFG_MAILBOX_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_mailbox_slaves,
@@ -2893,7 +2943,7 @@ static struct omap_hwmod omap44xx_mcbsp1_hwmod = {
.main_clk = "mcbsp1_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_mcbsp1_slaves,
@@ -2967,7 +3017,7 @@ static struct omap_hwmod omap44xx_mcbsp2_hwmod = {
.main_clk = "mcbsp2_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_mcbsp2_slaves,
@@ -3041,7 +3091,7 @@ static struct omap_hwmod omap44xx_mcbsp3_hwmod = {
.main_clk = "mcbsp3_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_mcbsp3_slaves,
@@ -3094,7 +3144,7 @@ static struct omap_hwmod omap44xx_mcbsp4_hwmod = {
.main_clk = "mcbsp4_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_mcbsp4_slaves,
@@ -3187,7 +3237,7 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = {
.main_clk = "mcpdm_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM1_ABE_PDM_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_mcpdm_slaves,
@@ -3273,7 +3323,7 @@ static struct omap_hwmod omap44xx_mcspi1_hwmod = {
.main_clk = "mcspi1_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI1_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET,
},
},
.dev_attr = &mcspi1_dev_attr,
@@ -3334,7 +3384,7 @@ static struct omap_hwmod omap44xx_mcspi2_hwmod = {
.main_clk = "mcspi2_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI2_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET,
},
},
.dev_attr = &mcspi2_dev_attr,
@@ -3395,7 +3445,7 @@ static struct omap_hwmod omap44xx_mcspi3_hwmod = {
.main_clk = "mcspi3_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI3_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET,
},
},
.dev_attr = &mcspi3_dev_attr,
@@ -3454,7 +3504,7 @@ static struct omap_hwmod omap44xx_mcspi4_hwmod = {
.main_clk = "mcspi4_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI4_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET,
},
},
.dev_attr = &mcspi4_dev_attr,
@@ -3539,7 +3589,7 @@ static struct omap_hwmod omap44xx_mmc1_hwmod = {
.main_clk = "mmc1_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L3INIT_MMC1_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET,
},
},
.dev_attr = &mmc1_dev_attr,
@@ -3599,7 +3649,7 @@ static struct omap_hwmod omap44xx_mmc2_hwmod = {
.main_clk = "mmc2_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L3INIT_MMC2_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_mmc2_slaves,
@@ -3654,7 +3704,7 @@ static struct omap_hwmod omap44xx_mmc3_hwmod = {
.main_clk = "mmc3_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_MMCSD3_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_mmc3_slaves,
@@ -3707,7 +3757,7 @@ static struct omap_hwmod omap44xx_mmc4_hwmod = {
.main_clk = "mmc4_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_MMCSD4_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_mmc4_slaves,
@@ -3760,7 +3810,7 @@ static struct omap_hwmod omap44xx_mmc5_hwmod = {
.main_clk = "mmc5_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_MMCSD5_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_mmc5_slaves,
@@ -3801,7 +3851,7 @@ static struct omap_hwmod omap44xx_mpu_hwmod = {
.main_clk = "dpll_mpu_m2_ck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_MPU_MPU_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET,
},
},
.masters = omap44xx_mpu_masters,
@@ -3874,7 +3924,7 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
.vdd_name = "core",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_smartreflex_core_slaves,
@@ -3921,7 +3971,7 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
.vdd_name = "iva",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_ALWON_SR_IVA_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_smartreflex_iva_slaves,
@@ -3968,7 +4018,7 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
.vdd_name = "mpu",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_ALWON_SR_MPU_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_smartreflex_mpu_slaves,
@@ -4030,7 +4080,7 @@ static struct omap_hwmod omap44xx_spinlock_hwmod = {
.clkdm_name = "l4_cfg_clkdm",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4CFG_HW_SEM_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_spinlock_slaves,
@@ -4114,7 +4164,7 @@ static struct omap_hwmod omap44xx_timer1_hwmod = {
.main_clk = "timer1_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_timer1_slaves,
@@ -4160,7 +4210,7 @@ static struct omap_hwmod omap44xx_timer2_hwmod = {
.main_clk = "timer2_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_timer2_slaves,
@@ -4206,7 +4256,7 @@ static struct omap_hwmod omap44xx_timer3_hwmod = {
.main_clk = "timer3_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_timer3_slaves,
@@ -4252,7 +4302,7 @@ static struct omap_hwmod omap44xx_timer4_hwmod = {
.main_clk = "timer4_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_timer4_slaves,
@@ -4317,7 +4367,7 @@ static struct omap_hwmod omap44xx_timer5_hwmod = {
.main_clk = "timer5_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_timer5_slaves,
@@ -4382,7 +4432,7 @@ static struct omap_hwmod omap44xx_timer6_hwmod = {
.main_clk = "timer6_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_timer6_slaves,
@@ -4447,7 +4497,7 @@ static struct omap_hwmod omap44xx_timer7_hwmod = {
.main_clk = "timer7_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_timer7_slaves,
@@ -4512,7 +4562,7 @@ static struct omap_hwmod omap44xx_timer8_hwmod = {
.main_clk = "timer8_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_timer8_slaves,
@@ -4558,7 +4608,7 @@ static struct omap_hwmod omap44xx_timer9_hwmod = {
.main_clk = "timer9_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_timer9_slaves,
@@ -4604,7 +4654,7 @@ static struct omap_hwmod omap44xx_timer10_hwmod = {
.main_clk = "timer10_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_timer10_slaves,
@@ -4650,7 +4700,7 @@ static struct omap_hwmod omap44xx_timer11_hwmod = {
.main_clk = "timer11_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_timer11_slaves,
@@ -4725,7 +4775,7 @@ static struct omap_hwmod omap44xx_uart1_hwmod = {
.main_clk = "uart1_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_UART1_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_uart1_slaves,
@@ -4778,7 +4828,7 @@ static struct omap_hwmod omap44xx_uart2_hwmod = {
.main_clk = "uart2_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_UART2_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_uart2_slaves,
@@ -4832,7 +4882,7 @@ static struct omap_hwmod omap44xx_uart3_hwmod = {
.main_clk = "uart3_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_UART3_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_uart3_slaves,
@@ -4885,7 +4935,7 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {
.main_clk = "uart4_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L4PER_UART4_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_uart4_slaves,
@@ -4964,7 +5014,7 @@ static struct omap_hwmod omap44xx_usb_otg_hs_hwmod = {
.main_clk = "usb_otg_hs_ick",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET,
},
},
.opt_clks = usb_otg_hs_opt_clks,
@@ -5037,7 +5087,7 @@ static struct omap_hwmod omap44xx_wd_timer2_hwmod = {
.main_clk = "wd_timer2_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM_WKUP_WDT2_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_wd_timer2_slaves,
@@ -5102,7 +5152,7 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
.main_clk = "wd_timer3_fck",
.prcm = {
.omap4 = {
- .clkctrl_reg = OMAP4430_CM1_ABE_WDT3_CLKCTRL,
+ .clkctrl_offs = OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET,
},
},
.slaves = omap44xx_wd_timer3_slaves,
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 28ea1c8..22864fd 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -362,7 +362,7 @@ struct omap_hwmod_omap2_prcm {
* @submodule_wkdep_bit: bit shift of the WKDEP range
*/
struct omap_hwmod_omap4_prcm {
- void __iomem *clkctrl_reg;
+ u16 clkctrl_offs;
void __iomem *rstctrl_reg;
u8 submodule_wkdep_bit;
};
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-06-24 11:05:52 UTC
Permalink
The RSTCTRL register was accessed using an absolute address.
The usage of hardcoded macros to calculate virtual address from physical
one should be avoided as much as possible.
The usage of an offset will allow future improvement like migration from
the current architecture code toward a module driver.

Update prm_xxx accessors, move definition to the proper header file and
update copyrights.
Change the s16 register offset parameter to u16.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Cc: Paul Walmsley <***@pwsan.com>
Cc: Rajendra Nayak <***@ti.com>
---
arch/arm/mach-omap2/omap_hwmod.c | 19 ++++--
arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 16 ++--
arch/arm/mach-omap2/prm44xx.c | 93 +-------------------------
arch/arm/mach-omap2/prm44xx.h | 4 -
arch/arm/mach-omap2/prminst44xx.c | 89 ++++++++++++++++++++++++-
arch/arm/mach-omap2/prminst44xx.h | 10 +++-
arch/arm/plat-omap/include/plat/omap_hwmod.h | 3 +-
7 files changed, 121 insertions(+), 113 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 8ac2546..5c0169c 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -148,6 +148,7 @@
#include "cminst44xx.h"
#include "prm2xxx_3xxx.h"
#include "prm44xx.h"
+#include "prminst44xx.h"
#include "mux.h"

/* Maximum microseconds to wait for OMAP module to softreset */
@@ -1110,8 +1111,10 @@ static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs,
ohri.rst_shift);
else if (cpu_is_omap44xx())
- return omap4_prm_assert_hardreset(oh->prcm.omap4.rstctrl_reg,
- ohri.rst_shift);
+ return omap4_prm_assert_hardreset(ohri.rst_shift,
+ oh->clkdm->pwrdm.ptr->prcm_partition,
+ oh->clkdm->pwrdm.ptr->prcm_offs,
+ oh->prcm.omap4.rstctrl_offs);
else
return -EINVAL;
}
@@ -1146,8 +1149,10 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
if (ohri.st_shift)
pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
oh->name, name);
- ret = omap4_prm_deassert_hardreset(oh->prcm.omap4.rstctrl_reg,
- ohri.rst_shift);
+ ret = omap4_prm_deassert_hardreset(ohri.rst_shift,
+ oh->clkdm->pwrdm.ptr->prcm_partition,
+ oh->clkdm->pwrdm.ptr->prcm_offs,
+ oh->prcm.omap4.rstctrl_offs);
} else {
return -EINVAL;
}
@@ -1182,8 +1187,10 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name)
return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs,
ohri.st_shift);
} else if (cpu_is_omap44xx()) {
- return omap4_prm_is_hardreset_asserted(oh->prcm.omap4.rstctrl_reg,
- ohri.rst_shift);
+ return omap4_prm_is_hardreset_asserted(ohri.rst_shift,
+ oh->clkdm->pwrdm.ptr->prcm_partition,
+ oh->clkdm->pwrdm.ptr->prcm_offs,
+ oh->prcm.omap4.rstctrl_offs);
} else {
return -EINVAL;
}
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index e4e50a8..1c0c96a 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -1141,7 +1141,7 @@ static struct omap_hwmod omap44xx_dsp_c0_hwmod = {
.rst_lines_cnt = ARRAY_SIZE(omap44xx_dsp_c0_resets),
.prcm = {
.omap4 = {
- .rstctrl_reg = OMAP4430_RM_TESLA_RSTCTRL,
+ .rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET,
},
},
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -1159,7 +1159,7 @@ static struct omap_hwmod omap44xx_dsp_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET,
- .rstctrl_reg = OMAP4430_RM_TESLA_RSTCTRL,
+ .rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET,
},
},
.slaves = omap44xx_dsp_slaves,
@@ -2481,7 +2481,7 @@ static struct omap_hwmod omap44xx_ipu_c0_hwmod = {
.rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_c0_resets),
.prcm = {
.omap4 = {
- .rstctrl_reg = OMAP4430_RM_DUCATI_RSTCTRL,
+ .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
},
},
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -2497,7 +2497,7 @@ static struct omap_hwmod omap44xx_ipu_c1_hwmod = {
.rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_c1_resets),
.prcm = {
.omap4 = {
- .rstctrl_reg = OMAP4430_RM_DUCATI_RSTCTRL,
+ .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
},
},
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -2515,7 +2515,7 @@ static struct omap_hwmod omap44xx_ipu_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET,
- .rstctrl_reg = OMAP4430_RM_DUCATI_RSTCTRL,
+ .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
},
},
.slaves = omap44xx_ipu_slaves,
@@ -2681,7 +2681,7 @@ static struct omap_hwmod omap44xx_iva_seq0_hwmod = {
.rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_seq0_resets),
.prcm = {
.omap4 = {
- .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL,
+ .rstctrl_offs = OMAP4_RM_IVAHD_RSTCTRL_OFFSET,
},
},
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -2697,7 +2697,7 @@ static struct omap_hwmod omap44xx_iva_seq1_hwmod = {
.rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_seq1_resets),
.prcm = {
.omap4 = {
- .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL,
+ .rstctrl_offs = OMAP4_RM_IVAHD_RSTCTRL_OFFSET,
},
},
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
@@ -2715,7 +2715,7 @@ static struct omap_hwmod omap44xx_iva_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET,
- .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL,
+ .rstctrl_offs = OMAP4_RM_IVAHD_RSTCTRL_OFFSET,
},
},
.slaves = omap44xx_iva_slaves,
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index a2a04bf..faec860 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -1,7 +1,7 @@
/*
* OMAP4 PRM module functions
*
- * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2011 Texas Instruments, Inc.
* Copyright (C) 2010 Nokia Corporation
* Benoît Cousson
* Paul Walmsley
@@ -24,12 +24,6 @@
#include "prm44xx.h"
#include "prm-regbits-44xx.h"

-/*
- * Address offset (in bytes) between the reset control and the reset
- * status registers: 4 bytes on OMAP4
- */
-#define OMAP4_RST_CTRL_ST_OFFSET 4
-
/* PRM low-level functions */

/* Read a register in a CM/PRM instance in the PRM module */
@@ -94,91 +88,6 @@ u32 omap4_prm_clear_inst_reg_bits(u32 bits, s16 inst, s16 reg)
return omap4_prm_rmw_inst_reg_bits(bits, 0x0, inst, reg);
}

-/**
- * omap4_prm_is_hardreset_asserted - read the HW reset line state of
- * submodules contained in the hwmod module
- * @rstctrl_reg: RM_RSTCTRL register address for this module
- * @shift: register bit shift corresponding to the reset line to check
- *
- * Returns 1 if the (sub)module hardreset line is currently asserted,
- * 0 if the (sub)module hardreset line is not currently asserted, or
- * -EINVAL upon parameter error.
- */
-int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift)
-{
- if (!cpu_is_omap44xx() || !rstctrl_reg)
- return -EINVAL;
-
- return omap4_prm_read_bits_shift(rstctrl_reg, (1 << shift));
-}
-
-/**
- * omap4_prm_assert_hardreset - assert the HW reset line of a submodule
- * @rstctrl_reg: RM_RSTCTRL register address for this module
- * @shift: register bit shift corresponding to the reset line to assert
- *
- * Some IPs like dsp, ipu or iva contain processors that require an HW
- * reset line to be asserted / deasserted in order to fully enable the
- * IP. These modules may have multiple hard-reset lines that reset
- * different 'submodules' inside the IP block. This function will
- * place the submodule into reset. Returns 0 upon success or -EINVAL
- * upon an argument error.
- */
-int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift)
-{
- u32 mask;
-
- if (!cpu_is_omap44xx() || !rstctrl_reg)
- return -EINVAL;
-
- mask = 1 << shift;
- omap4_prm_rmw_reg_bits(mask, mask, rstctrl_reg);
-
- return 0;
-}
-
-/**
- * omap4_prm_deassert_hardreset - deassert a submodule hardreset line and wait
- * @rstctrl_reg: RM_RSTCTRL register address for this module
- * @shift: register bit shift corresponding to the reset line to deassert
- *
- * Some IPs like dsp, ipu or iva contain processors that require an HW
- * reset line to be asserted / deasserted in order to fully enable the
- * IP. These modules may have multiple hard-reset lines that reset
- * different 'submodules' inside the IP block. This function will
- * take the submodule out of reset and wait until the PRCM indicates
- * that the reset has completed before returning. Returns 0 upon success or
- * -EINVAL upon an argument error, -EEXIST if the submodule was already out
- * of reset, or -EBUSY if the submodule did not exit reset promptly.
- */
-int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift)
-{
- u32 mask;
- void __iomem *rstst_reg;
- int c;
-
- if (!cpu_is_omap44xx() || !rstctrl_reg)
- return -EINVAL;
-
- rstst_reg = rstctrl_reg + OMAP4_RST_CTRL_ST_OFFSET;
-
- mask = 1 << shift;
-
- /* Check the current status to avoid de-asserting the line twice */
- if (omap4_prm_read_bits_shift(rstctrl_reg, mask) == 0)
- return -EEXIST;
-
- /* Clear the reset status by writing 1 to the status bit */
- omap4_prm_rmw_reg_bits(0xffffffff, mask, rstst_reg);
- /* de-assert the reset control line */
- omap4_prm_rmw_reg_bits(mask, 0, rstctrl_reg);
- /* wait the status to be set */
- omap_test_timeout(omap4_prm_read_bits_shift(rstst_reg, mask),
- MAX_MODULE_HARDRESET_WAIT, c);
-
- return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
-}
-
void omap4_prm_global_warm_sw_reset(void)
{
u32 v;
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index 11e878f..21b0240 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -691,10 +691,6 @@ extern u32 omap4_prm_set_inst_reg_bits(u32 bits, s16 inst, s16 idx);
extern u32 omap4_prm_clear_inst_reg_bits(u32 bits, s16 inst, s16 idx);
extern u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask);

-extern int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift);
-extern int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift);
-extern int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift);
-
extern void omap4_prm_global_warm_sw_reset(void);

# endif
diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c
index a303242..67e9e46 100644
--- a/arch/arm/mach-omap2/prminst44xx.c
+++ b/arch/arm/mach-omap2/prminst44xx.c
@@ -2,6 +2,7 @@
* OMAP4 PRM instance functions
*
* Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2011 Texas Instruments, Inc.
* Paul Walmsley
*
* This program is free software; you can redistribute it and/or modify
@@ -53,7 +54,7 @@ void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx)

/* Read-modify-write a register in PRM. Caller must lock */
u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
- s16 idx)
+ u16 idx)
{
u32 v;

@@ -64,3 +65,89 @@ u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,

return v;
}
+
+/*
+ * Address offset (in bytes) between the reset control and the reset
+ * status registers: 4 bytes on OMAP4
+ */
+#define OMAP4_RST_CTRL_ST_OFFSET 4
+
+/**
+ * omap4_prm_is_hardreset_asserted - read the HW reset line state of
+ * submodules contained in the hwmod module
+ * @rstctrl_reg: RM_RSTCTRL register address for this module
+ * @shift: register bit shift corresponding to the reset line to check
+ *
+ * Returns 1 if the (sub)module hardreset line is currently asserted,
+ * 0 if the (sub)module hardreset line is not currently asserted, or
+ * -EINVAL upon parameter error.
+ */
+int omap4_prm_is_hardreset_asserted(u8 shift, u8 part, s16 inst,
+ u16 rstctrl_offs)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(part, inst, rstctrl_offs);
+ v &= 1 << shift;
+ v >>= shift;
+
+ return v;
+}
+
+/**
+ * omap4_prm_assert_hardreset - assert the HW reset line of a submodule
+ * @rstctrl_reg: RM_RSTCTRL register address for this module
+ * @shift: register bit shift corresponding to the reset line to assert
+ *
+ * Some IPs like dsp, ipu or iva contain processors that require an HW
+ * reset line to be asserted / deasserted in order to fully enable the
+ * IP. These modules may have multiple hard-reset lines that reset
+ * different 'submodules' inside the IP block. This function will
+ * place the submodule into reset. Returns 0 upon success or -EINVAL
+ * upon an argument error.
+ */
+int omap4_prm_assert_hardreset(u8 shift, u8 part, s16 inst,
+ u16 rstctrl_offs)
+{
+ u32 mask = 1 << shift;
+
+ omap4_prminst_rmw_inst_reg_bits(mask, mask, part, inst, rstctrl_offs);
+
+ return 0;
+}
+
+/**
+ * omap4_prm_deassert_hardreset - deassert a submodule hardreset line and wait
+ * @rstctrl_reg: RM_RSTCTRL register address for this module
+ * @shift: register bit shift corresponding to the reset line to deassert
+ *
+ * Some IPs like dsp, ipu or iva contain processors that require an HW
+ * reset line to be asserted / deasserted in order to fully enable the
+ * IP. These modules may have multiple hard-reset lines that reset
+ * different 'submodules' inside the IP block. This function will
+ * take the submodule out of reset and wait until the PRCM indicates
+ * that the reset has completed before returning. Returns 0 upon success or
+ * -EINVAL upon an argument error, -EEXIST if the submodule was already out
+ * of reset, or -EBUSY if the submodule did not exit reset promptly.
+ */
+int omap4_prm_deassert_hardreset(u8 shift, u8 part, s16 inst,
+ u16 rstctrl_offs)
+{
+ int c;
+ u32 mask = 1 << shift;
+ u16 rstst_offs = rstctrl_offs + OMAP4_RST_CTRL_ST_OFFSET;
+
+ /* Check the current status to avoid de-asserting the line twice */
+ if (omap4_prm_is_hardreset_asserted(mask, part, inst, rstctrl_offs) == 0)
+ return -EEXIST;
+
+ /* Clear the reset status by writing 1 to the status bit */
+ omap4_prminst_rmw_inst_reg_bits(0xffffffff, mask, part, inst, rstst_offs);
+ /* de-assert the reset control line */
+ omap4_prminst_rmw_inst_reg_bits(mask, 0, part, inst, rstst_offs);
+ /* wait the status to be set */
+ omap_test_timeout(omap4_prm_is_hardreset_asserted(mask, part, inst, rstst_offs),
+ MAX_MODULE_HARDRESET_WAIT, c);
+
+ return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
+}
diff --git a/arch/arm/mach-omap2/prminst44xx.h b/arch/arm/mach-omap2/prminst44xx.h
index 02dd66d..80e930e 100644
--- a/arch/arm/mach-omap2/prminst44xx.h
+++ b/arch/arm/mach-omap2/prminst44xx.h
@@ -2,6 +2,7 @@
* OMAP4 Power/Reset Management (PRM) function prototypes
*
* Copyright (C) 2010 Nokia Corporation
+ * Copyright (C) 2011 Texas Instruments, Inc.
* Paul Walmsley
*
* This program is free software; you can redistribute it and/or modify
@@ -18,8 +19,15 @@
extern u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx);
extern void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx);
extern u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part,
- s16 inst, s16 idx);
+ s16 inst, u16 idx);

extern void omap4_prm_global_warm_sw_reset(void);

+extern int omap4_prm_is_hardreset_asserted(u8 shift, u8 part, s16 inst,
+ u16 rstctrl_offs);
+extern int omap4_prm_assert_hardreset(u8 shift, u8 part, s16 inst,
+ u16 rstctrl_offs);
+extern int omap4_prm_deassert_hardreset(u8 shift, u8 part, s16 inst,
+ u16 rstctrl_offs);
+
#endif
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 22864fd..75bf4fa 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -2,6 +2,7 @@
* omap_hwmod macros, structures
*
* Copyright (C) 2009-2011 Nokia Corporation
+ * Copyright (C) 2011 Texas Instruments, Inc.
* Paul Walmsley
*
* Created in collaboration with (alphabetical order): Benoît Cousson,
@@ -363,7 +364,7 @@ struct omap_hwmod_omap2_prcm {
*/
struct omap_hwmod_omap4_prcm {
u16 clkctrl_offs;
- void __iomem *rstctrl_reg;
+ u16 rstctrl_offs;
u8 submodule_wkdep_bit;
};
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-06-24 11:05:50 UTC
Permalink
It is mandatory to wait for a module to be in disabled state before
potentially disabling source clock or re-asserting a reset.

omap_hwmod_idle and omap_hwmod_shutdown does not wait for
the module to be fully idle.

Add a cm_xxx accessor to wait the clkctrl idle status to be disabled.
Fix hwmod_[idle|shutdown] to use this API.

Based on Rajendra's initial patch.

Please note that most interconnects hwmod will return one timeout because
it is impossible for them to be in idle since the processor is accessing
the registers though the interconnect.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Signed-off-by: Rajendra Nayak <***@ti.com>
Cc: Paul Walmsley <***@pwsan.com>
---
arch/arm/mach-omap2/cminst44xx.c | 22 ++++++++++++++++++++
arch/arm/mach-omap2/cminst44xx.h | 1 +
arch/arm/mach-omap2/omap_hwmod.c | 40 ++++++++++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
index 6fa0ebb..83498c1 100644
--- a/arch/arm/mach-omap2/cminst44xx.c
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -241,3 +241,25 @@ int omap4_cm_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs)
return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
}

+/**
+ * omap4_cm_wait_module_idle - wait for a module to be in 'disabled'
+ * state
+ * @part: PRCM partition ID that the CM_CLKCTRL register exists in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
+ *
+ * Wait for the module IDLEST to be disabled. Some PRCM transition,
+ * like reset assertion or parent clock de-activation must wait the
+ * module to be fully disabled.
+ */
+int omap4_cm_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs)
+{
+ int i = 0;
+
+ omap_test_timeout(
+ _clkctrl_idlest(part, inst, cdoffs, clkctrl_offs) == 0x3,
+ MAX_MODULE_READY_TIME, i);
+
+ return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
+}
diff --git a/arch/arm/mach-omap2/cminst44xx.h b/arch/arm/mach-omap2/cminst44xx.h
index 9d39c70..4c5da7d 100644
--- a/arch/arm/mach-omap2/cminst44xx.h
+++ b/arch/arm/mach-omap2/cminst44xx.h
@@ -18,6 +18,7 @@ extern void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs);
extern void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs);

extern int omap4_cm_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs);
+extern int omap4_cm_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs);

/*
* In an ideal world, we would not export these low-level functions,
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index ea1c976..617ad21 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1029,6 +1029,36 @@ static int _wait_target_ready(struct omap_hwmod *oh)
}

/**
+ * _wait_target_disable - wait for a module to be disabled
+ * @oh: struct omap_hwmod *
+ *
+ * Wait for a module @oh to leave slave idle. Returns 0 if the module
+ * does not have an IDLEST bit or if the module successfully leaves
+ * slave idle; otherwise, pass along the return value of the
+ * appropriate *_cm_wait_module_ready() function.
+ */
+static int _wait_target_disable(struct omap_hwmod *oh)
+{
+ if (!oh)
+ return -EINVAL;
+
+ if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
+ return 0;
+
+ if (oh->flags & HWMOD_NO_IDLEST)
+ return 0;
+
+ /* TODO: For now just handle OMAP4+ */
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ return 0;
+
+ return omap4_cm_wait_module_idle(oh->clkdm->prcm_partition,
+ oh->clkdm->cm_inst,
+ oh->clkdm->clkdm_offs,
+ oh->prcm.omap4.clkctrl_offs);
+}
+
+/**
* _lookup_hardreset - fill register bit info for this hwmod/reset line
* @oh: struct omap_hwmod *
* @name: name of the reset line in the context of this hwmod
@@ -1335,6 +1365,8 @@ static int _enable(struct omap_hwmod *oh)
*/
static int _idle(struct omap_hwmod *oh)
{
+ int ret;
+
if (oh->_state != _HWMOD_STATE_ENABLED) {
WARN(1, "omap_hwmod: %s: idle state can only be entered from "
"enabled state\n", oh->name);
@@ -1347,6 +1379,10 @@ static int _idle(struct omap_hwmod *oh)
_idle_sysc(oh);
_del_initiator_dep(oh, mpu_oh);
_disable_clocks(oh);
+ ret = _wait_target_disable(oh);
+ if (ret)
+ pr_warning("omap_hwmod: %s: _wait_target_disable failed\n",
+ oh->name);

/* Mux pins for device idle if populated */
if (oh->mux && oh->mux->pads_dynamic)
@@ -1439,6 +1475,10 @@ static int _shutdown(struct omap_hwmod *oh)
_del_initiator_dep(oh, mpu_oh);
/* XXX what about the other system initiators here? dma, dsp */
_disable_clocks(oh);
+ ret = _wait_target_disable(oh);
+ if (ret)
+ pr_warning("omap_hwmod: %s: _wait_target_disable failed\n",
+ oh->name);
}
/* XXX Should this code also force-disable the optional clocks? */
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-06-24 11:05:55 UTC
Permalink
The interconnect modules were using a slightly different layout than
the regular modules.
Align the layout for better consitency.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Cc: Paul Walmsley <***@pwsan.com>
Cc: Rajendra Nayak <***@ti.com>
---
arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 48 ++++++++++++++--------------
1 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 1c0c96a..06df473 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -80,7 +80,11 @@ static struct omap_hwmod_class omap44xx_dmm_hwmod_class = {
.name = "dmm",
};

-/* dmm interface data */
+/* dmm */
+static struct omap_hwmod_irq_info omap44xx_dmm_irqs[] = {
+ { .irq = 113 + OMAP44XX_IRQ_GIC_START },
+};
+
/* l3_main_1 -> dmm */
static struct omap_hwmod_ocp_if omap44xx_l3_main_1__dmm = {
.master = &omap44xx_l3_main_1_hwmod,
@@ -113,14 +117,12 @@ static struct omap_hwmod_ocp_if *omap44xx_dmm_slaves[] = {
&omap44xx_mpu__dmm,
};

-static struct omap_hwmod_irq_info omap44xx_dmm_irqs[] = {
- { .irq = 113 + OMAP44XX_IRQ_GIC_START },
-};
-
static struct omap_hwmod omap44xx_dmm_hwmod = {
.name = "dmm",
.class = &omap44xx_dmm_hwmod_class,
.clkdm_name = "l3_emif_clkdm",
+ .mpu_irqs = omap44xx_dmm_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dmm_irqs),
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET,
@@ -128,8 +130,6 @@ static struct omap_hwmod omap44xx_dmm_hwmod = {
},
.slaves = omap44xx_dmm_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dmm_slaves),
- .mpu_irqs = omap44xx_dmm_irqs,
- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dmm_irqs),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};

@@ -141,7 +141,7 @@ static struct omap_hwmod_class omap44xx_emif_fw_hwmod_class = {
.name = "emif_fw",
};

-/* emif_fw interface data */
+/* emif_fw */
/* dmm -> emif_fw */
static struct omap_hwmod_ocp_if omap44xx_dmm__emif_fw = {
.master = &omap44xx_dmm_hwmod,
@@ -196,7 +196,7 @@ static struct omap_hwmod_class omap44xx_l3_hwmod_class = {
.name = "l3",
};

-/* l3_instr interface data */
+/* l3_instr */
/* iva -> l3_instr */
static struct omap_hwmod_ocp_if omap44xx_iva__l3_instr = {
.master = &omap44xx_iva_hwmod,
@@ -233,7 +233,12 @@ static struct omap_hwmod omap44xx_l3_instr_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};

-/* l3_main_1 interface data */
+/* l3_main_1 */
+static struct omap_hwmod_irq_info omap44xx_l3_main_1_irqs[] = {
+ { .name = "dbg_err", .irq = 9 + OMAP44XX_IRQ_GIC_START },
+ { .name = "app_err", .irq = 10 + OMAP44XX_IRQ_GIC_START },
+};
+
/* dsp -> l3_main_1 */
static struct omap_hwmod_ocp_if omap44xx_dsp__l3_main_1 = {
.master = &omap44xx_dsp_hwmod,
@@ -311,15 +316,12 @@ static struct omap_hwmod_ocp_if *omap44xx_l3_main_1_slaves[] = {
&omap44xx_mpu__l3_main_1,
};

-static struct omap_hwmod_irq_info omap44xx_l3_main_1_irqs[] = {
- { .name = "dbg_err", .irq = 9 + OMAP44XX_IRQ_GIC_START },
- { .name = "app_err", .irq = 10 + OMAP44XX_IRQ_GIC_START },
-};
-
static struct omap_hwmod omap44xx_l3_main_1_hwmod = {
.name = "l3_main_1",
.class = &omap44xx_l3_hwmod_class,
.clkdm_name = "l3_1_clkdm",
+ .mpu_irqs = omap44xx_l3_main_1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_l3_main_1_irqs),
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET,
@@ -327,12 +329,10 @@ static struct omap_hwmod omap44xx_l3_main_1_hwmod = {
},
.slaves = omap44xx_l3_main_1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_1_slaves),
- .mpu_irqs = omap44xx_l3_main_1_irqs,
- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_l3_main_1_irqs),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};

-/* l3_main_2 interface data */
+/* l3_main_2 */
/* dma_system -> l3_main_2 */
static struct omap_hwmod_ocp_if omap44xx_dma_system__l3_main_2 = {
.master = &omap44xx_dma_system_hwmod,
@@ -433,7 +433,7 @@ static struct omap_hwmod omap44xx_l3_main_2_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};

-/* l3_main_3 interface data */
+/* l3_main_3 */
static struct omap_hwmod_addr_space omap44xx_l3_main_3_addrs[] = {
{
.pa_start = 0x45000000,
@@ -497,7 +497,7 @@ static struct omap_hwmod_class omap44xx_l4_hwmod_class = {
.name = "l4",
};

-/* l4_abe interface data */
+/* l4_abe */
/* aess -> l4_abe */
static struct omap_hwmod_ocp_if omap44xx_aess__l4_abe = {
.master = &omap44xx_aess_hwmod,
@@ -552,7 +552,7 @@ static struct omap_hwmod omap44xx_l4_abe_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};

-/* l4_cfg interface data */
+/* l4_cfg */
/* l3_main_1 -> l4_cfg */
static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l4_cfg = {
.master = &omap44xx_l3_main_1_hwmod,
@@ -580,7 +580,7 @@ static struct omap_hwmod omap44xx_l4_cfg_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};

-/* l4_per interface data */
+/* l4_per */
/* l3_main_2 -> l4_per */
static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l4_per = {
.master = &omap44xx_l3_main_2_hwmod,
@@ -608,7 +608,7 @@ static struct omap_hwmod omap44xx_l4_per_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP44XX),
};

-/* l4_wkup interface data */
+/* l4_wkup */
/* l4_cfg -> l4_wkup */
static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l4_wkup = {
.master = &omap44xx_l4_cfg_hwmod,
@@ -644,7 +644,7 @@ static struct omap_hwmod_class omap44xx_mpu_bus_hwmod_class = {
.name = "mpu_bus",
};

-/* mpu_private interface data */
+/* mpu_private */
/* mpu -> mpu_private */
static struct omap_hwmod_ocp_if omap44xx_mpu__mpu_private = {
.master = &omap44xx_mpu_hwmod,
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-06-24 11:05:53 UTC
Permalink
The warm reset function was still using the obsolete API.
Replace it by the new one and move the file to the proper c file.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Cc: Paul Walmsley <***@pwsan.com>
Cc: Rajendra Nayak <***@ti.com>
---
arch/arm/mach-omap2/prm44xx.c | 15 ---------------
arch/arm/mach-omap2/prm44xx.h | 2 --
arch/arm/mach-omap2/prminst44xx.c | 19 +++++++++++++++++++
3 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index faec860..f815329 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -87,18 +87,3 @@ u32 omap4_prm_clear_inst_reg_bits(u32 bits, s16 inst, s16 reg)
{
return omap4_prm_rmw_inst_reg_bits(bits, 0x0, inst, reg);
}
-
-void omap4_prm_global_warm_sw_reset(void)
-{
- u32 v;
-
- v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
- OMAP4_RM_RSTCTRL);
- v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
- omap4_prm_write_inst_reg(v, OMAP4430_PRM_DEVICE_INST,
- OMAP4_RM_RSTCTRL);
-
- /* OCP barrier */
- v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
- OMAP4_RM_RSTCTRL);
-}
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index 21b0240..a3887b8 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -691,8 +691,6 @@ extern u32 omap4_prm_set_inst_reg_bits(u32 bits, s16 inst, s16 idx);
extern u32 omap4_prm_clear_inst_reg_bits(u32 bits, s16 inst, s16 idx);
extern u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask);

-extern void omap4_prm_global_warm_sw_reset(void);
-
# endif

#endif
diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c
index 67e9e46..1e29b9c 100644
--- a/arch/arm/mach-omap2/prminst44xx.c
+++ b/arch/arm/mach-omap2/prminst44xx.c
@@ -151,3 +151,22 @@ int omap4_prm_deassert_hardreset(u8 shift, u8 part, s16 inst,

return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
}
+
+
+void omap4_prm_global_warm_sw_reset(void)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_DEVICE_INST,
+ OMAP4_PRM_RSTCTRL_OFFSET);
+ v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
+ omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_DEVICE_INST,
+ OMAP4_PRM_RSTCTRL_OFFSET);
+
+ /* OCP barrier */
+ v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_DEVICE_INST,
+ OMAP4_PRM_RSTCTRL_OFFSET);
+}
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-06-24 11:05:54 UTC
Permalink
The new prminst_xxx accessors based on partition and offset
is now used, so removed all the previous prcm_xxx accessors.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Cc: Paul Walmsley <***@pwsan.com>
Cc: Rajendra Nayak <***@ti.com>
---
arch/arm/mach-omap2/prm44xx.c | 37 -------------------------------------
1 files changed, 0 insertions(+), 37 deletions(-)

diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index f815329..0016555 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -50,40 +50,3 @@ u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg)

return v;
}
-
-/* Read a PRM register, AND it, and shift the result down to bit 0 */
-/* XXX deprecated */
-u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask)
-{
- u32 v;
-
- v = __raw_readl(reg);
- v &= mask;
- v >>= __ffs(mask);
-
- return v;
-}
-
-/* Read-modify-write a register in a PRM module. Caller must lock */
-/* XXX deprecated */
-u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg)
-{
- u32 v;
-
- v = __raw_readl(reg);
- v &= ~mask;
- v |= bits;
- __raw_writel(v, reg);
-
- return v;
-}
-
-u32 omap4_prm_set_inst_reg_bits(u32 bits, s16 inst, s16 reg)
-{
- return omap4_prm_rmw_inst_reg_bits(bits, bits, inst, reg);
-}
-
-u32 omap4_prm_clear_inst_reg_bits(u32 bits, s16 inst, s16 reg)
-{
- return omap4_prm_rmw_inst_reg_bits(bits, 0x0, inst, reg);
-}
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-06-24 11:05:56 UTC
Permalink
Add a 'context_offs' entry in the prcm.omap4 structure to all
IPs when applicable.
The offset will be used to retrieve the per module context lost
information now available on OMAP4.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Cc: Paul Walmsley <***@pwsan.com>
Cc: Rajendra Nayak <***@ti.com>
---
arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 74 ++++++++++++++++++++++++++
arch/arm/plat-omap/include/plat/omap_hwmod.h | 1 +
2 files changed, 75 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 06df473..0f692fd 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -126,6 +126,7 @@ static struct omap_hwmod omap44xx_dmm_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_MEMIF_DMM_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_dmm_slaves,
@@ -181,6 +182,7 @@ static struct omap_hwmod omap44xx_emif_fw_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_MEMIF_EMIF_FW_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_emif_fw_slaves,
@@ -226,6 +228,7 @@ static struct omap_hwmod omap44xx_l3_instr_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_l3_instr_slaves,
@@ -325,6 +328,7 @@ static struct omap_hwmod omap44xx_l3_main_1_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_l3_main_1_slaves,
@@ -426,6 +430,7 @@ static struct omap_hwmod omap44xx_l3_main_2_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3_2_L3_2_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_l3_main_2_slaves,
@@ -482,6 +487,7 @@ static struct omap_hwmod omap44xx_l3_main_3_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INSTR_L3_3_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_l3_main_3_slaves,
@@ -573,6 +579,7 @@ static struct omap_hwmod omap44xx_l4_cfg_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4CFG_L4_CFG_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_l4_cfg_slaves,
@@ -601,6 +608,7 @@ static struct omap_hwmod omap44xx_l4_per_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_L4_PER_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_l4_per_slaves,
@@ -629,6 +637,7 @@ static struct omap_hwmod omap44xx_l4_wkup_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_WKUP_L4WKUP_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_WKUP_L4WKUP_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_l4_wkup_slaves,
@@ -807,6 +816,7 @@ static struct omap_hwmod omap44xx_aess_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_AESS_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_aess_slaves,
@@ -897,6 +907,7 @@ static struct omap_hwmod omap44xx_counter_32k_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_WKUP_SYNCTIMER_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_counter_32k_slaves,
@@ -981,6 +992,7 @@ static struct omap_hwmod omap44xx_dma_system_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_SDMA_SDMA_CONTEXT_OFFSET,
},
},
.dev_attr = &dma_dev_attr,
@@ -1075,6 +1087,7 @@ static struct omap_hwmod omap44xx_dmic_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_DMIC_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_dmic_slaves,
@@ -1160,6 +1173,7 @@ static struct omap_hwmod omap44xx_dsp_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET,
.rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET,
+ .context_offs = OMAP4_RM_TESLA_TESLA_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_dsp_slaves,
@@ -1248,6 +1262,7 @@ static struct omap_hwmod omap44xx_dss_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
},
},
.opt_clks = dss_opt_clks,
@@ -1346,6 +1361,7 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_dss_dispc_slaves,
@@ -1438,6 +1454,7 @@ static struct omap_hwmod omap44xx_dss_dsi1_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_dss_dsi1_slaves,
@@ -1509,6 +1526,7 @@ static struct omap_hwmod omap44xx_dss_dsi2_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_dss_dsi2_slaves,
@@ -1600,6 +1618,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_dss_hdmi_slaves,
@@ -1685,6 +1704,7 @@ static struct omap_hwmod omap44xx_dss_rfbi_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_dss_rfbi_slaves,
@@ -1753,6 +1773,7 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_dss_venc_slaves,
@@ -1832,6 +1853,7 @@ static struct omap_hwmod omap44xx_gpio1_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_WKUP_GPIO1_CONTEXT_OFFSET,
},
},
.opt_clks = gpio1_opt_clks,
@@ -1886,6 +1908,7 @@ static struct omap_hwmod omap44xx_gpio2_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_GPIO2_CONTEXT_OFFSET,
},
},
.opt_clks = gpio2_opt_clks,
@@ -1940,6 +1963,7 @@ static struct omap_hwmod omap44xx_gpio3_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_GPIO3_CONTEXT_OFFSET,
},
},
.opt_clks = gpio3_opt_clks,
@@ -1994,6 +2018,7 @@ static struct omap_hwmod omap44xx_gpio4_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_GPIO4_CONTEXT_OFFSET,
},
},
.opt_clks = gpio4_opt_clks,
@@ -2048,6 +2073,7 @@ static struct omap_hwmod omap44xx_gpio5_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_GPIO5_CONTEXT_OFFSET,
},
},
.opt_clks = gpio5_opt_clks,
@@ -2102,6 +2128,7 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_GPIO6_CONTEXT_OFFSET,
},
},
.opt_clks = gpio6_opt_clks,
@@ -2181,6 +2208,7 @@ static struct omap_hwmod omap44xx_hsi_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INIT_HSI_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_hsi_slaves,
@@ -2258,6 +2286,7 @@ static struct omap_hwmod omap44xx_i2c1_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_I2C1_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_i2c1_slaves,
@@ -2312,6 +2341,7 @@ static struct omap_hwmod omap44xx_i2c2_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_I2C2_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_i2c2_slaves,
@@ -2366,6 +2396,7 @@ static struct omap_hwmod omap44xx_i2c3_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_I2C3_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_i2c3_slaves,
@@ -2420,6 +2451,7 @@ static struct omap_hwmod omap44xx_i2c4_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_I2C4_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_i2c4_slaves,
@@ -2516,6 +2548,7 @@ static struct omap_hwmod omap44xx_ipu_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET,
.rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
+ .context_offs = OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_ipu_slaves,
@@ -2602,6 +2635,7 @@ static struct omap_hwmod omap44xx_iss_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_CAM_ISS_CONTEXT_OFFSET,
},
},
.opt_clks = iss_opt_clks,
@@ -2716,6 +2750,7 @@ static struct omap_hwmod omap44xx_iva_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET,
.rstctrl_offs = OMAP4_RM_IVAHD_RSTCTRL_OFFSET,
+ .context_offs = OMAP4_RM_IVAHD_IVAHD_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_iva_slaves,
@@ -2786,6 +2821,7 @@ static struct omap_hwmod omap44xx_kbd_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_WKUP_KEYBOARD_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_kbd_slaves,
@@ -2851,6 +2887,7 @@ static struct omap_hwmod omap44xx_mailbox_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4CFG_MAILBOX_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_mailbox_slaves,
@@ -2944,6 +2981,7 @@ static struct omap_hwmod omap44xx_mcbsp1_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_MCBSP1_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_mcbsp1_slaves,
@@ -3018,6 +3056,7 @@ static struct omap_hwmod omap44xx_mcbsp2_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_MCBSP2_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_mcbsp2_slaves,
@@ -3092,6 +3131,7 @@ static struct omap_hwmod omap44xx_mcbsp3_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_MCBSP3_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_mcbsp3_slaves,
@@ -3145,6 +3185,7 @@ static struct omap_hwmod omap44xx_mcbsp4_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MCBSP4_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_mcbsp4_slaves,
@@ -3238,6 +3279,7 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_PDM_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_mcpdm_slaves,
@@ -3324,6 +3366,7 @@ static struct omap_hwmod omap44xx_mcspi1_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MCSPI1_CONTEXT_OFFSET,
},
},
.dev_attr = &mcspi1_dev_attr,
@@ -3385,6 +3428,7 @@ static struct omap_hwmod omap44xx_mcspi2_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MCSPI2_CONTEXT_OFFSET,
},
},
.dev_attr = &mcspi2_dev_attr,
@@ -3446,6 +3490,7 @@ static struct omap_hwmod omap44xx_mcspi3_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MCSPI3_CONTEXT_OFFSET,
},
},
.dev_attr = &mcspi3_dev_attr,
@@ -3505,6 +3550,7 @@ static struct omap_hwmod omap44xx_mcspi4_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MCSPI4_CONTEXT_OFFSET,
},
},
.dev_attr = &mcspi4_dev_attr,
@@ -3590,6 +3636,7 @@ static struct omap_hwmod omap44xx_mmc1_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INIT_MMC1_CONTEXT_OFFSET,
},
},
.dev_attr = &mmc1_dev_attr,
@@ -3650,6 +3697,7 @@ static struct omap_hwmod omap44xx_mmc2_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INIT_MMC2_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_mmc2_slaves,
@@ -3705,6 +3753,7 @@ static struct omap_hwmod omap44xx_mmc3_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MMCSD3_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_mmc3_slaves,
@@ -3758,6 +3807,7 @@ static struct omap_hwmod omap44xx_mmc4_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MMCSD4_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_mmc4_slaves,
@@ -3811,6 +3861,7 @@ static struct omap_hwmod omap44xx_mmc5_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_MMCSD5_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_mmc5_slaves,
@@ -3852,6 +3903,7 @@ static struct omap_hwmod omap44xx_mpu_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_MPU_MPU_CONTEXT_OFFSET,
},
},
.masters = omap44xx_mpu_masters,
@@ -3925,6 +3977,7 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ALWON_SR_CORE_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_smartreflex_core_slaves,
@@ -3972,6 +4025,7 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ALWON_SR_IVA_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_smartreflex_iva_slaves,
@@ -4019,6 +4073,7 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ALWON_SR_MPU_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_smartreflex_mpu_slaves,
@@ -4081,6 +4136,7 @@ static struct omap_hwmod omap44xx_spinlock_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4CFG_HW_SEM_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_spinlock_slaves,
@@ -4165,6 +4221,7 @@ static struct omap_hwmod omap44xx_timer1_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_WKUP_TIMER1_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_timer1_slaves,
@@ -4211,6 +4268,7 @@ static struct omap_hwmod omap44xx_timer2_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_DMTIMER2_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_timer2_slaves,
@@ -4257,6 +4315,7 @@ static struct omap_hwmod omap44xx_timer3_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_DMTIMER3_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_timer3_slaves,
@@ -4303,6 +4362,7 @@ static struct omap_hwmod omap44xx_timer4_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_DMTIMER4_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_timer4_slaves,
@@ -4368,6 +4428,7 @@ static struct omap_hwmod omap44xx_timer5_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_TIMER5_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_timer5_slaves,
@@ -4433,6 +4494,7 @@ static struct omap_hwmod omap44xx_timer6_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_TIMER6_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_timer6_slaves,
@@ -4498,6 +4560,7 @@ static struct omap_hwmod omap44xx_timer7_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_TIMER7_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_timer7_slaves,
@@ -4563,6 +4626,7 @@ static struct omap_hwmod omap44xx_timer8_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_TIMER8_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_timer8_slaves,
@@ -4609,6 +4673,7 @@ static struct omap_hwmod omap44xx_timer9_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_DMTIMER9_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_timer9_slaves,
@@ -4655,6 +4720,7 @@ static struct omap_hwmod omap44xx_timer10_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_DMTIMER10_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_timer10_slaves,
@@ -4701,6 +4767,7 @@ static struct omap_hwmod omap44xx_timer11_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_DMTIMER11_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_timer11_slaves,
@@ -4776,6 +4843,7 @@ static struct omap_hwmod omap44xx_uart1_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_UART1_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_uart1_slaves,
@@ -4829,6 +4897,7 @@ static struct omap_hwmod omap44xx_uart2_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_UART2_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_uart2_slaves,
@@ -4883,6 +4952,7 @@ static struct omap_hwmod omap44xx_uart3_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_UART3_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_uart3_slaves,
@@ -4936,6 +5006,7 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L4PER_UART4_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_uart4_slaves,
@@ -5015,6 +5086,7 @@ static struct omap_hwmod omap44xx_usb_otg_hs_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_L3INIT_USB_OTG_CONTEXT_OFFSET,
},
},
.opt_clks = usb_otg_hs_opt_clks,
@@ -5088,6 +5160,7 @@ static struct omap_hwmod omap44xx_wd_timer2_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_WKUP_WDT2_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_wd_timer2_slaves,
@@ -5153,6 +5226,7 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET,
+ .context_offs = OMAP4_RM_ABE_WDT3_CONTEXT_OFFSET,
},
},
.slaves = omap44xx_wd_timer3_slaves,
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 75bf4fa..40e561e 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -365,6 +365,7 @@ struct omap_hwmod_omap2_prcm {
struct omap_hwmod_omap4_prcm {
u16 clkctrl_offs;
u16 rstctrl_offs;
+ u16 context_offs;
u8 submodule_wkdep_bit;
};
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-06-24 11:05:57 UTC
Permalink
Add a new field to provide the mode supported by the module.
The mode will control the way mandatory clocks are managed by the PRCM.

0 : Module is temporarily disabled by SW. OCP access to module are stalled.
Can be used to change timing parameter of GPMC module.
1 : Module is managed automatically by HW according to clock domain
transition. A clock domain sleep transition put module into idle.
A wakeup domain transition put it back into function.
If CLKTRCTRL=3, any OCP access to module is always granted.
Module clocks may be gated according to the clock domain state.
2 : Module is explicitly enabled. Interface clock (if not used for
functions) may be gated according to the clock domain state.
Functional clocks are guarantied to stay present. As long as
in this configuration, power domain sleep transition cannot happen.

Some modules will have a modulemode initialized at 1 (HWCTRL) by default.
This is the case for interconnect and simple module like GPIO, WDT, MAILBOX.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Cc: Paul Walmsley <***@pwsan.com>
Cc: Rajendra Nayak <***@ti.com>
---
arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 56 ++++++++++++++++++++++++++
arch/arm/plat-omap/include/plat/omap_hwmod.h | 6 +++
2 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 0f692fd..850ac39 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -229,6 +229,7 @@ static struct omap_hwmod omap44xx_l3_instr_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
},
},
.slaves = omap44xx_l3_instr_slaves,
@@ -488,6 +489,7 @@ static struct omap_hwmod omap44xx_l3_main_3_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L3INSTR_L3_3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
},
},
.slaves = omap44xx_l3_main_3_slaves,
@@ -817,6 +819,7 @@ static struct omap_hwmod omap44xx_aess_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_ABE_AESS_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_aess_slaves,
@@ -1088,6 +1091,7 @@ static struct omap_hwmod omap44xx_dmic_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_ABE_DMIC_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_dmic_slaves,
@@ -1174,6 +1178,7 @@ static struct omap_hwmod omap44xx_dsp_hwmod = {
.clkctrl_offs = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET,
.rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET,
.context_offs = OMAP4_RM_TESLA_TESLA_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
},
},
.slaves = omap44xx_dsp_slaves,
@@ -1263,6 +1268,7 @@ static struct omap_hwmod omap44xx_dss_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.opt_clks = dss_opt_clks,
@@ -1854,6 +1860,7 @@ static struct omap_hwmod omap44xx_gpio1_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_WKUP_GPIO1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
},
},
.opt_clks = gpio1_opt_clks,
@@ -1909,6 +1916,7 @@ static struct omap_hwmod omap44xx_gpio2_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_GPIO2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
},
},
.opt_clks = gpio2_opt_clks,
@@ -1964,6 +1972,7 @@ static struct omap_hwmod omap44xx_gpio3_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_GPIO3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
},
},
.opt_clks = gpio3_opt_clks,
@@ -2019,6 +2028,7 @@ static struct omap_hwmod omap44xx_gpio4_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_GPIO4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
},
},
.opt_clks = gpio4_opt_clks,
@@ -2074,6 +2084,7 @@ static struct omap_hwmod omap44xx_gpio5_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_GPIO5_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
},
},
.opt_clks = gpio5_opt_clks,
@@ -2129,6 +2140,7 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_GPIO6_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
},
},
.opt_clks = gpio6_opt_clks,
@@ -2209,6 +2221,7 @@ static struct omap_hwmod omap44xx_hsi_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L3INIT_HSI_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
},
},
.slaves = omap44xx_hsi_slaves,
@@ -2287,6 +2300,7 @@ static struct omap_hwmod omap44xx_i2c1_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_I2C1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_i2c1_slaves,
@@ -2342,6 +2356,7 @@ static struct omap_hwmod omap44xx_i2c2_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_I2C2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_i2c2_slaves,
@@ -2397,6 +2412,7 @@ static struct omap_hwmod omap44xx_i2c3_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_I2C3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_i2c3_slaves,
@@ -2452,6 +2468,7 @@ static struct omap_hwmod omap44xx_i2c4_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_I2C4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_i2c4_slaves,
@@ -2549,6 +2566,7 @@ static struct omap_hwmod omap44xx_ipu_hwmod = {
.clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET,
.rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
.context_offs = OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
},
},
.slaves = omap44xx_ipu_slaves,
@@ -2636,6 +2654,7 @@ static struct omap_hwmod omap44xx_iss_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_CAM_ISS_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.opt_clks = iss_opt_clks,
@@ -2751,6 +2770,7 @@ static struct omap_hwmod omap44xx_iva_hwmod = {
.clkctrl_offs = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET,
.rstctrl_offs = OMAP4_RM_IVAHD_RSTCTRL_OFFSET,
.context_offs = OMAP4_RM_IVAHD_IVAHD_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
},
},
.slaves = omap44xx_iva_slaves,
@@ -2822,6 +2842,7 @@ static struct omap_hwmod omap44xx_kbd_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_WKUP_KEYBOARD_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_kbd_slaves,
@@ -2982,6 +3003,7 @@ static struct omap_hwmod omap44xx_mcbsp1_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_ABE_MCBSP1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_mcbsp1_slaves,
@@ -3057,6 +3079,7 @@ static struct omap_hwmod omap44xx_mcbsp2_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_ABE_MCBSP2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_mcbsp2_slaves,
@@ -3132,6 +3155,7 @@ static struct omap_hwmod omap44xx_mcbsp3_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_ABE_MCBSP3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_mcbsp3_slaves,
@@ -3186,6 +3210,7 @@ static struct omap_hwmod omap44xx_mcbsp4_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_MCBSP4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_mcbsp4_slaves,
@@ -3280,6 +3305,7 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_ABE_PDM_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_mcpdm_slaves,
@@ -3367,6 +3393,7 @@ static struct omap_hwmod omap44xx_mcspi1_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_MCSPI1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.dev_attr = &mcspi1_dev_attr,
@@ -3429,6 +3456,7 @@ static struct omap_hwmod omap44xx_mcspi2_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_MCSPI2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.dev_attr = &mcspi2_dev_attr,
@@ -3491,6 +3519,7 @@ static struct omap_hwmod omap44xx_mcspi3_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_MCSPI3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.dev_attr = &mcspi3_dev_attr,
@@ -3551,6 +3580,7 @@ static struct omap_hwmod omap44xx_mcspi4_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_MCSPI4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.dev_attr = &mcspi4_dev_attr,
@@ -3637,6 +3667,7 @@ static struct omap_hwmod omap44xx_mmc1_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L3INIT_MMC1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.dev_attr = &mmc1_dev_attr,
@@ -3698,6 +3729,7 @@ static struct omap_hwmod omap44xx_mmc2_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L3INIT_MMC2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_mmc2_slaves,
@@ -3754,6 +3786,7 @@ static struct omap_hwmod omap44xx_mmc3_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_MMCSD3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_mmc3_slaves,
@@ -3808,6 +3841,7 @@ static struct omap_hwmod omap44xx_mmc4_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_MMCSD4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_mmc4_slaves,
@@ -3862,6 +3896,7 @@ static struct omap_hwmod omap44xx_mmc5_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_MMCSD5_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_mmc5_slaves,
@@ -3978,6 +4013,7 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_ALWON_SR_CORE_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_smartreflex_core_slaves,
@@ -4026,6 +4062,7 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_ALWON_SR_IVA_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_smartreflex_iva_slaves,
@@ -4074,6 +4111,7 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_ALWON_SR_MPU_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_smartreflex_mpu_slaves,
@@ -4222,6 +4260,7 @@ static struct omap_hwmod omap44xx_timer1_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_WKUP_TIMER1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_timer1_slaves,
@@ -4269,6 +4308,7 @@ static struct omap_hwmod omap44xx_timer2_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_DMTIMER2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_timer2_slaves,
@@ -4316,6 +4356,7 @@ static struct omap_hwmod omap44xx_timer3_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_DMTIMER3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_timer3_slaves,
@@ -4363,6 +4404,7 @@ static struct omap_hwmod omap44xx_timer4_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_DMTIMER4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_timer4_slaves,
@@ -4429,6 +4471,7 @@ static struct omap_hwmod omap44xx_timer5_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_ABE_TIMER5_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_timer5_slaves,
@@ -4495,6 +4538,7 @@ static struct omap_hwmod omap44xx_timer6_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_ABE_TIMER6_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_timer6_slaves,
@@ -4561,6 +4605,7 @@ static struct omap_hwmod omap44xx_timer7_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_ABE_TIMER7_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_timer7_slaves,
@@ -4627,6 +4672,7 @@ static struct omap_hwmod omap44xx_timer8_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_ABE_TIMER8_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_timer8_slaves,
@@ -4674,6 +4720,7 @@ static struct omap_hwmod omap44xx_timer9_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_DMTIMER9_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_timer9_slaves,
@@ -4721,6 +4768,7 @@ static struct omap_hwmod omap44xx_timer10_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_DMTIMER10_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_timer10_slaves,
@@ -4768,6 +4816,7 @@ static struct omap_hwmod omap44xx_timer11_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_DMTIMER11_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_timer11_slaves,
@@ -4844,6 +4893,7 @@ static struct omap_hwmod omap44xx_uart1_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_UART1_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_uart1_slaves,
@@ -4898,6 +4948,7 @@ static struct omap_hwmod omap44xx_uart2_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_UART2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_uart2_slaves,
@@ -4953,6 +5004,7 @@ static struct omap_hwmod omap44xx_uart3_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_UART3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_uart3_slaves,
@@ -5007,6 +5059,7 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L4PER_UART4_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_uart4_slaves,
@@ -5087,6 +5140,7 @@ static struct omap_hwmod omap44xx_usb_otg_hs_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_L3INIT_USB_OTG_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_HWCTRL,
},
},
.opt_clks = usb_otg_hs_opt_clks,
@@ -5161,6 +5215,7 @@ static struct omap_hwmod omap44xx_wd_timer2_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_WKUP_WDT2_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_wd_timer2_slaves,
@@ -5227,6 +5282,7 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_ABE_WDT3_CONTEXT_OFFSET,
+ .modulemode = MODULEMODE_SWCTRL,
},
},
.slaves = omap44xx_wd_timer3_slaves,
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 40e561e..7df9fa2 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -80,6 +80,11 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
#define HWMOD_IDLEMODE_SMART (1 << 2)
#define HWMOD_IDLEMODE_SMART_WKUP (1 << 3)

+/* modulemode control type (SW or HW) */
+#define MODULEMODE_HWCTRL 1
+#define MODULEMODE_SWCTRL 2
+
+
/**
* struct omap_hwmod_mux_info - hwmod specific mux configuration
* @pads: array of omap_device_pad entries
@@ -367,6 +372,7 @@ struct omap_hwmod_omap4_prcm {
u16 rstctrl_offs;
u16 context_offs;
u8 submodule_wkdep_bit;
+ u8 modulemode;
};
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-06-24 11:05:58 UTC
Permalink
In OMAP4, a new programming model based on module control instead
of clock control was introduced.
Expose two APIs to allow the upper layer (omap_hwmod) to control
the module mode independently of the parent clocks management.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Cc: Paul Walmsley <***@pwsan.com>
Cc: Rajendra Nayak <***@ti.com>
---
arch/arm/mach-omap2/cminst44xx.c | 38 ++++++++++++++++++++++++++++++++++++++
arch/arm/mach-omap2/cminst44xx.h | 3 +++
2 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
index 83498c1..3176ea6 100644
--- a/arch/arm/mach-omap2/cminst44xx.c
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -263,3 +263,41 @@ int omap4_cm_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs)

return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
}
+
+/**
+ * omap4_cm_module_enable - Enable the modulemode inside CLKCTRL
+ * @mode: Module mode (SW or HW)
+ * @part: PRCM partition ID that the CM_CLKCTRL register exists in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
+ * No return value.
+ */
+void omap4_cm_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs,
+ u16 clkctrl_offs)
+{
+ u32 v;
+
+ v = omap4_cminst_read_inst_reg(part, inst, cdoffs + clkctrl_offs);
+ v &= ~OMAP4430_MODULEMODE_MASK;
+ v |= mode << OMAP4430_MODULEMODE_SHIFT;
+ omap4_cminst_write_inst_reg(v, part, inst, cdoffs + clkctrl_offs);
+}
+
+/**
+ * omap4_cm_module_disable - Disable the module inside CLKCTRL
+ * @part: PRCM partition ID that the CM_CLKCTRL register exists in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
+ * No return value.
+ */
+void omap4_cm_module_disable(u8 part, u16 inst, s16 cdoffs,
+ u16 clkctrl_offs)
+{
+ u32 v;
+
+ v = omap4_cminst_read_inst_reg(part, inst, cdoffs + clkctrl_offs);
+ v &= ~OMAP4430_MODULEMODE_MASK;
+ omap4_cminst_write_inst_reg(v, part, inst, cdoffs + clkctrl_offs);
+}
diff --git a/arch/arm/mach-omap2/cminst44xx.h b/arch/arm/mach-omap2/cminst44xx.h
index 4c5da7d..8034e5c 100644
--- a/arch/arm/mach-omap2/cminst44xx.h
+++ b/arch/arm/mach-omap2/cminst44xx.h
@@ -20,6 +20,9 @@ extern void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs);
extern int omap4_cm_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs);
extern int omap4_cm_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs);

+extern void omap4_cm_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs);
+extern void omap4_cm_module_disable(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs);
+
/*
* In an ideal world, we would not export these low-level functions,
* but this will probably take some time to fix properly
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-06-24 11:05:59 UTC
Permalink
Take advantage of the explicit modulemode control to fix
the way parents clocks are managed.
A module must be disabled before any parents are disabled.
That programming model was not possible with the previous
implementation that was considering a modulemode as a leaf
clock node managed by the clock fmwk.
This was leading to bad crash upon disable when the parent
clock was gated before the module completed its transition
to idle.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Cc: Paul Walmsley <***@pwsan.com>
Cc: Rajendra Nayak <***@ti.com>
---
arch/arm/mach-omap2/omap_hwmod.c | 63 ++++++++++++++++++++++++++++++++++++-
1 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 5c0169c..6b144c4 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -675,6 +675,56 @@ static void _disable_optional_clocks(struct omap_hwmod *oh)
}

/**
+ * _enable_module - enable CLKCTRL modulemode on OMAP4
+ * @oh: struct omap_hwmod *
+ *
+ * Enables the PRCM module mode related to the hwmod @oh.
+ * No return value.
+ */
+static void _enable_module(struct omap_hwmod *oh)
+{
+ /* The module mode does not exist prior OMAP4 */
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ return;
+
+ if (!oh->clkdm || !oh->prcm.omap4.modulemode)
+ return;
+
+ pr_debug("omap_hwmod: %s: _enable_module: %d\n",
+ oh->name, oh->prcm.omap4.modulemode);
+
+ omap4_cm_module_enable(oh->prcm.omap4.modulemode,
+ oh->clkdm->prcm_partition,
+ oh->clkdm->cm_inst,
+ oh->clkdm->clkdm_offs,
+ oh->prcm.omap4.clkctrl_offs);
+}
+
+/**
+ * _disable_module - enable CLKCTRL modulemode on OMAP4
+ * @oh: struct omap_hwmod *
+ *
+ * Disable the PRCM module mode related to the hwmod @oh.
+ * No return value.
+ */
+static void _disable_module(struct omap_hwmod *oh)
+{
+ /* The module mode does not exist prior OMAP4 */
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ return;
+
+ if (!oh->clkdm || !oh->prcm.omap4.modulemode)
+ return;
+
+ pr_debug("omap_hwmod: %s: _disable_module\n", oh->name);
+
+ omap4_cm_module_disable(oh->clkdm->prcm_partition,
+ oh->clkdm->cm_inst,
+ oh->clkdm->clkdm_offs,
+ oh->prcm.omap4.clkctrl_offs);
+}
+
+/**
* _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use
* @oh: struct omap_hwmod *
*
@@ -1329,6 +1379,7 @@ static int _enable(struct omap_hwmod *oh)

_add_initiator_dep(oh, mpu_oh);
_enable_clocks(oh);
+ _enable_module(oh);

/*
* If an IP contains only one HW reset line, then de-assert it in order
@@ -1381,11 +1432,18 @@ static int _idle(struct omap_hwmod *oh)
if (oh->class->sysc)
_idle_sysc(oh);
_del_initiator_dep(oh, mpu_oh);
- _disable_clocks(oh);
+ _disable_module(oh);
ret = _wait_target_disable(oh);
if (ret)
pr_warning("omap_hwmod: %s: _wait_target_disable failed\n",
oh->name);
+ /*
+ * The module must be in idle mode before disabling any parents
+ * clocks. Otherwise, the parent clock might be disabled before
+ * the module transition is done, and thus will prevent the
+ * transition to complete properly.
+ */
+ _disable_clocks(oh);

/* Mux pins for device idle if populated */
if (oh->mux && oh->mux->pads_dynamic)
@@ -1477,11 +1535,12 @@ static int _shutdown(struct omap_hwmod *oh)
if (oh->_state == _HWMOD_STATE_ENABLED) {
_del_initiator_dep(oh, mpu_oh);
/* XXX what about the other system initiators here? dma, dsp */
- _disable_clocks(oh);
+ _disable_module(oh);
ret = _wait_target_disable(oh);
if (ret)
pr_warning("omap_hwmod: %s: _wait_target_disable failed\n",
oh->name);
+ _disable_clocks(oh);
}
/* XXX Should this code also force-disable the optional clocks? */
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-06-24 11:06:00 UTC
Permalink
From: Nayak, Rajendra <***@ti.com>

Add a clockdomain api to check if hardware supervised
idle transitions are enabled on a clockdomain.

Signed-off-by: Rajendra Nayak <***@ti.com>
---
arch/arm/mach-omap2/clockdomain.c | 21 +++++++++++++++++++++
arch/arm/mach-omap2/clockdomain.h | 3 +++
2 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 6cb6c03..2ab3686 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -795,6 +795,27 @@ void clkdm_deny_idle(struct clockdomain *clkdm)
arch_clkdm->clkdm_deny_idle(clkdm);
}

+/**
+ * clkdm_is_idle - Check if the clkdm hwsup/autoidle is enabled
+ * @clkdm: struct clockdomain *
+ *
+ * Returns true if the clockdomain is in hardware-supervised
+ * idle mode, or 0 otherwise.
+ *
+ */
+int clkdm_is_idle(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return -EINVAL;
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_is_idle)
+ return -EINVAL;
+
+ pr_debug("clockdomain: reading idle state for %s\n", clkdm->name);
+
+ return arch_clkdm->clkdm_is_idle(clkdm);
+}
+

/* Clockdomain-to-clock framework interface code */

diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 5823584..085ed82 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -138,6 +138,7 @@ struct clockdomain {
* @clkdm_wakeup: Force a clockdomain to wakeup
* @clkdm_allow_idle: Enable hw supervised idle transitions for clock domain
* @clkdm_deny_idle: Disable hw supervised idle transitions for clock domain
+ * @clkdm_is_idle: Check if hw supervised idle transitions are enabled
* @clkdm_clk_enable: Put the clkdm in right state for a clock enable
* @clkdm_clk_disable: Put the clkdm in right state for a clock disable
*/
@@ -154,6 +155,7 @@ struct clkdm_ops {
int (*clkdm_wakeup)(struct clockdomain *clkdm);
void (*clkdm_allow_idle)(struct clockdomain *clkdm);
void (*clkdm_deny_idle)(struct clockdomain *clkdm);
+ int (*clkdm_is_idle)(struct clockdomain *clkdm);
int (*clkdm_clk_enable)(struct clockdomain *clkdm);
int (*clkdm_clk_disable)(struct clockdomain *clkdm);
};
@@ -177,6 +179,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);

void clkdm_allow_idle(struct clockdomain *clkdm);
void clkdm_deny_idle(struct clockdomain *clkdm);
+int clkdm_is_idle(struct clockdomain *clkdm);

int clkdm_wakeup(struct clockdomain *clkdm);
int clkdm_sleep(struct clockdomain *clkdm);
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Todd Poynor
2011-06-26 17:51:41 UTC
Permalink
Post by Benoit Cousson
Add a clockdomain api to check if hardware supervised
idle transitions are enabled on a clockdomain.
...
Post by Benoit Cousson
+ * clkdm_is_idle - Check if the clkdm hwsup/autoidle is enabled
+ *
+ * Returns true if the clockdomain is in hardware-supervised
+ * idle mode, or 0 otherwise.
+ *
+ */
+int clkdm_is_idle(struct clockdomain *clkdm)
...
Post by Benoit Cousson
void clkdm_allow_idle(struct clockdomain *clkdm);
void clkdm_deny_idle(struct clockdomain *clkdm);
+int clkdm_is_idle(struct clockdomain *clkdm);
Suggest the new API be named clkdm_allows_idle, since it tests that
hardware-supervised idle is allowed (perhaps via a call to
clkdm_allow_idle), and not that the clock domain is necessarily
idle at the time of call.


Todd
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Sundaram Raju
2011-07-10 15:03:23 UTC
Permalink
Added new dma_ctrl_cmd TI_DMA_STRIDE_CONFIG to pass the TI DMA
controller specific configurations on how a buffer must be walked
through and how data is picked for transfer based on a specified
pattern over the channel.

The configuration passed is specific to the TI DMA controller used.

Signed-off-by: Sundaram Raju <sundaram-***@public.gmane.org>
---
include/linux/dmaengine.h | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index eee7add..51dadc4 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -123,6 +123,10 @@ enum dma_ctrl_flags {
* command.
* @FSLDMA_EXTERNAL_START: this command will put the Freescale DMA controller
* into external start mode.
+ * @TI_DMA_STRIDE_CONFIG: this command is only implemented by TI DMA
+ * controllers that need to pass special configuration on how to walk through
+ * the buffer to pick up data in a specified pattern to be transferred in
+ * the channel.
*/
enum dma_ctrl_cmd {
DMA_TERMINATE_ALL,
@@ -130,6 +134,7 @@ enum dma_ctrl_cmd {
DMA_RESUME,
DMA_SLAVE_CONFIG,
FSLDMA_EXTERNAL_START,
+ TI_DMA_STRIDE_CONFIG,
};

/**
--
1.6.2.4
Linus Walleij
2011-07-11 09:28:24 UTC
Permalink
Post by Sundaram Raju
Added new dma_ctrl_cmd TI_DMA_STRIDE_CONFIG to pass the TI DMA
controller specific configurations on how a buffer must be walked
through and how data is picked for transfer based on a specified
pattern over the channel.
The configuration passed is specific to the TI DMA controller used.
This is exactly how I think we should do this.
Acked-by: Linus Walleij <***@linaro.org>

Thanks,
Linus Walleij
Dan Williams
2011-07-11 21:39:17 UTC
Permalink
Post by Linus Walleij
Post by Sundaram Raju
Added new dma_ctrl_cmd TI_DMA_STRIDE_CONFIG to pass the TI DMA
controller specific configurations on how a buffer must be walked
through and how data is picked for transfer based on a specified
pattern over the channel.
The configuration passed is specific to the TI DMA controller used.
...and I suspect the slave device drivers that use TI DMA are not
expected to ever work with other dmaengines? Likely the case, but
just wondering out loud.
Post by Linus Walleij
This is exactly how I think we should do this.
Linus Walleij
2011-07-12 09:58:04 UTC
Permalink
Post by Dan Williams
...and I suspect the slave device drivers that use TI DMA are not
expected to ever work with other dmaengines? =A0Likely the case, but
just wondering out loud.
Typically the OMAP/TI drivers are one-to-one with this specific DMA
controller, but they *can* support controllers without stride options, =
and
notice that striding will only be used for the display driver IIRC,
pseudo-code:

ret =3D dmaengine_device_control(chan, TI_DMA_STRIDE_CONFIG,
(unsigned long) &my_stride_config);
if (ret) {
/*
* OK no striding on this DMA engine, fall back to something else,
* such as creating an SGlist which emulates the striding with one
* sglist element per stride.
*/
}

By injecting an error in the stride config path this can even be
properly tested. So it will become an optional acceleration.

Thanks,
Linus Walleij
Raju, Sundaram
2011-07-12 10:15:47 UTC
Permalink
Post by Pillai, Manikandan
-----Original Message-----
Sent: Tuesday, July 12, 2011 3:28 PM
To: Dan Williams
m;
Post by Pillai, Manikandan
Subject: Re: [PATCH] dmaengine: add dma_ctrl_cmd to pass buffer strid=
e
Post by Pillai, Manikandan
configuration
=20
com>
o.org>
Post by Pillai, Manikandan
=20
Post by Dan Williams
...and I suspect the slave device drivers that use TI DMA are not
expected to ever work with other dmaengines? =A0Likely the case, bu=
t
Post by Pillai, Manikandan
Post by Dan Williams
just wondering out loud.
=20
Typically the OMAP/TI drivers are one-to-one with this specific DMA
controller, but they *can* support controllers without stride options=
, and
Post by Pillai, Manikandan
notice that striding will only be used for the display driver IIRC,
=20
ret =3D dmaengine_device_control(chan, TI_DMA_STRIDE_CONFIG,
(unsigned long) &my_stride_config);
if (ret) {
/*
* OK no striding on this DMA engine, fall back to something else,
* such as creating an SGlist which emulates the striding with one
* sglist element per stride.
*/
}
=20
By injecting an error in the stride config path this can even be
properly tested. So it will become an optional acceleration.
Yes, this is exactly what I also wanted to say. :)

But if the client driver does not implement a fallback like this then t=
hat
driver will work only with TI DMA and not any other dmaengines.
(Mentioning this because, there are client drivers which are tightly=20
coupled to this special configuration)

Keeping this in mind, I had started the original discussion with
the suggestion of modifying the existing prepare API and adding
an extra argument to it, which can be used to pass special configuratio=
n.
And I also wanted to generalize that configuration passed.

Anyways that design also will come down to this same path, and instead
of modifying the existing API signatures, I think this is the best way
we can go.

Regards,
Sundaram
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" i=
n
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Jassi Brar
2011-07-12 04:17:19 UTC
Permalink
Post by Sundaram Raju
Added new dma_ctrl_cmd TI_DMA_STRIDE_CONFIG to pass the TI DMA
controller specific configurations on how a buffer must be walked
through and how data is picked for transfer based on a specified
pattern over the channel.
The configuration passed is specific to the TI DMA controller used.
---
=C2=A0include/linux/dmaengine.h | =C2=A0 =C2=A05 +++++
=C2=A01 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index eee7add..51dadc4 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -123,6 +123,10 @@ enum dma_ctrl_flags {
=C2=A0* command.
MA controller
Post by Sundaram Raju
=C2=A0* into external start mode.
+ * controllers that need to pass special configuration on how to wal=
k through
Post by Sundaram Raju
+ * the buffer to pick up data in a specified pattern to be transferr=
ed in
Post by Sundaram Raju
+ * the channel.
=C2=A0*/
=C2=A0enum dma_ctrl_cmd {
=C2=A0 =C2=A0 =C2=A0 =C2=A0DMA_TERMINATE_ALL,
@@ -130,6 +134,7 @@ enum dma_ctrl_cmd {
=C2=A0 =C2=A0 =C2=A0 =C2=A0DMA_RESUME,
=C2=A0 =C2=A0 =C2=A0 =C2=A0DMA_SLAVE_CONFIG,
=C2=A0 =C2=A0 =C2=A0 =C2=A0FSLDMA_EXTERNAL_START,
+ =C2=A0 =C2=A0 =C2=A0 TI_DMA_STRIDE_CONFIG,
=C2=A0};
IMHO this isn't very correct.

1) Striding, in one form or other, is supported by other DMACs as well.
The number will only increase in future.
Are we to add <VENDOR>_DMA_STRIDE_CONFIG for each case ?

2) As Dan noted, client drivers are going to have ifdef hackery in
order to be common
to other SoCs.

3) TI may not have just one DMAC IP used in all the SoCs. So if you wan=
t
vendor specific defines anyway, please atleast also add DMAC version =
to it.
Something like
Post by Sundaram Raju
DMA_SLAVE_CONFIG,
FSLDMA_EXTERNAL_START,
+ TI_DMA_v1_STRIDE_CONFIG,
Linus Walleij
2011-07-12 10:03:22 UTC
Permalink
1) Striding, in one form or other, is supported by other DMACs as wel=
l.
=A0 The number will only increase in future.
=A0 Are we to add =A0<VENDOR>_DMA_STRIDE_CONFIG for each case ?
If we are sure about this and striding will work in a similar way on al=
l
then let's have the enum named DMA_STRIDE_CONFIG and move the
passed-in struct to <linux/dmaengine.h) then?

Would that be:

struct dma_stride_config {
u32 read_bytes;
u32 skip_bytes;
};

Or something more complex?
2) As Dan noted, client drivers are going to have ifdef hackery in
order to be common
=A0to other SoCs.
Don't think so, why? This is a runtime config entirely, and I just illu=
strated
in mail to Dan how that can be handled by falling back to a sglist I be=
lieve?

We can *maybe* even put the fallback code into dmaengine, so that an
emulated sglist in place for the DMAengine is done automatically of the
DMA controller does not support striding.
3) TI may not have just one DMAC IP used in all the SoCs. So if you w=
ant
=A0vendor specific defines anyway, please atleast also add DMAC versi=
on to it.
=A0Something like
=A0 =A0 =A0 =A0DMA_SLAVE_CONFIG,
=A0 =A0 =A0 =A0FSLDMA_EXTERNAL_START,
+ =A0 =A0 =A0 TI_DMA_v1_STRIDE_CONFIG,
Yep unless we make it generic DMA_STRIDE_CONFIG simply, this makes
a lot of sense.

Linus Walleij
Raju, Sundaram
2011-07-12 10:56:32 UTC
Permalink
Post by Pillai, Manikandan
-----Original Message-----
Sent: Tuesday, July 12, 2011 3:33 PM
To: Jassi Brar
m;
nel.org
Post by Pillai, Manikandan
Subject: Re: [PATCH] dmaengine: add dma_ctrl_cmd to pass buffer strid=
e
Post by Pillai, Manikandan
configuration
=20
=20
1) Striding, in one form or other, is supported by other DMACs as w=
ell.
Post by Pillai, Manikandan
=A0 The number will only increase in future.
=A0 Are we to add =A0<VENDOR>_DMA_STRIDE_CONFIG for each case ?
=20
If we are sure about this and striding will work in a similar way on =
all
Post by Pillai, Manikandan
then let's have the enum named DMA_STRIDE_CONFIG and move the
passed-in struct to <linux/dmaengine.h) then?
=20
=20
struct dma_stride_config {
u32 read_bytes;
u32 skip_bytes;
};
=20
Or something more complex?
=20
When I started this discussion on stride config, I received comments li=
ke
this is too specific to TI DMAC, and there are not many DMACs which can
do this. I actually wanted to generalize the configuration passed and p=
ut
a comment on it similar to the one on top of dma_slave_config, which sa=
ys

|
|/**
<snip>
| * The rationale for adding configuration information to this struct
| * is as follows: if it is likely that most DMA slave controllers in
| * the world will support the configuration option, then make it
| * generic. If not: if it is fixed so that it be sent in static from
| * the platform data, then prefer to do that. Else, if it is neither
| * fixed at runtime, nor generic enough (such as bus mastership on
| * some CPU family and whatnot) then create a custom slave config
| * struct and pass that, then make this config a member of that
| * struct, if applicable.
| */
|

If any other DMAC can do similar stride configuration,
then we can generalize it.=20

Till we generalize this stride configuration I think a custom
configuration aligned between the client driver and
the offload engine driver can be used.
Post by Pillai, Manikandan
2) As Dan noted, client drivers are going to have ifdef hackery in
order to be common
=A0to other SoCs.
=20
Don't think so, why? This is a runtime config entirely, and I just il=
lustrated
Post by Pillai, Manikandan
in mail to Dan how that can be handled by falling back to a sglist I =
believe?
Post by Pillai, Manikandan
=20
We can *maybe* even put the fallback code into dmaengine, so that an
emulated sglist in place for the DMAengine is done automatically of t=
he
Post by Pillai, Manikandan
DMA controller does not support striding.
=20
Good Idea.

But the client might always have a better way to handle this fallback t=
han
this suggested fallback code in dmaengine, which will be a common
implementation based on the received sg_list and the DMAC capabilities.
If this is done then preference should be provided to the client's fall=
back
implementation, if present.
Post by Pillai, Manikandan
3) TI may not have just one DMAC IP used in all the SoCs. So if you=
want
Post by Pillai, Manikandan
=A0vendor specific defines anyway, please atleast also add DMAC ver=
sion to it.
Post by Pillai, Manikandan
=A0Something like
=A0 =A0 =A0 =A0DMA_SLAVE_CONFIG,
=A0 =A0 =A0 =A0FSLDMA_EXTERNAL_START,
+ =A0 =A0 =A0 TI_DMA_v1_STRIDE_CONFIG,
=20
Yep unless we make it generic DMA_STRIDE_CONFIG simply, this makes
a lot of sense.
Okay, I can add one cmd for the EDMAC in DaVinci series of SoCs and=20
one for SDMAC in OMAP series of SoCs.

Regards,
Sundaram
Linus Walleij
2011-07-12 11:09:31 UTC
Permalink
Post by Raju, Sundaram
[Me]
[Jassi]
3) TI may not have just one DMAC IP used in all the SoCs. So if yo=
u want
Post by Raju, Sundaram
=A0vendor specific defines anyway, please atleast also add DMAC ve=
rsion to it.
Post by Raju, Sundaram
=A0Something like
=A0 =A0 =A0 =A0DMA_SLAVE_CONFIG,
=A0 =A0 =A0 =A0FSLDMA_EXTERNAL_START,
+ =A0 =A0 =A0 TI_DMA_v1_STRIDE_CONFIG,
Yep unless we make it generic DMA_STRIDE_CONFIG simply, this makes
a lot of sense.
Okay, I can add one cmd for the EDMAC in DaVinci series of SoCs and
one for SDMAC in OMAP series of SoCs.
Wait, that's two different silicon blocks right? Then you already have =
proof
that this spans more than one DMAC and then you can just go for a gener=
ic
DMA_STRIDE_CONFIG from day one.

That both are TI does not matter, if they are totally unrelated impleme=
ntations.

Yours,
Linus Walleij
Jassi Brar
2011-07-12 11:20:37 UTC
Permalink
Post by Pillai, Manikandan
1) Striding, in one form or other, is supported by other DMACs as we=
ll.
Post by Pillai, Manikandan
=C2=A0 The number will only increase in future.
=C2=A0 Are we to add =C2=A0<VENDOR>_DMA_STRIDE_CONFIG for each case =
?
Post by Pillai, Manikandan
If we are sure about this and striding will work in a similar way on =
all
Post by Pillai, Manikandan
then let's have the enum named DMA_STRIDE_CONFIG and move the
passed-in struct to <linux/dmaengine.h) then?
struct dma_stride_config {
=C2=A0 =C2=A0u32 read_bytes;
=C2=A0 =C2=A0u32 skip_bytes;
};
Or something more complex?
Well, I am not sure if striding needs any special treatment at all.
Why not have client drivers prepare and submit sg-list.
Let the DMAC drivers interpret/parse the sg-list and program it
as strides if the h/w supports it.
If anything, we should make preparation and submission of sg-list
as efficient as possible.
Post by Pillai, Manikandan
2) As Dan noted, client drivers are going to have ifdef hackery in
order to be common
=C2=A0to other SoCs.
Don't think so, why? This is a runtime config entirely, and I just il=
lustrated
Post by Pillai, Manikandan
in mail to Dan how that can be handled by falling back to a sglist I =
believe?
Runtime decision isn't neat either.
What if a client driver is common to 'N' SoCs each with different DMACs=
?
We would need a switch construct !
Raju, Sundaram
2011-07-12 11:31:23 UTC
Permalink
Post by Pillai, Manikandan
-----Original Message-----
Sent: Tuesday, July 12, 2011 4:51 PM
To: Linus Walleij
Subject: Re: [PATCH] dmaengine: add dma_ctrl_cmd to pass buffer stride
configuration
Post by Jassi Brar
1) Striding, in one form or other, is supported by other DMACs as well.
  The number will only increase in future.
  Are we to add  <VENDOR>_DMA_STRIDE_CONFIG for each case ?
If we are sure about this and striding will work in a similar way on all
then let's have the enum named DMA_STRIDE_CONFIG and move the
passed-in struct to <linux/dmaengine.h) then?
struct dma_stride_config {
   u32 read_bytes;
   u32 skip_bytes;
};
Or something more complex?
Well, I am not sure if striding needs any special treatment at all.
Why not have client drivers prepare and submit sg-list.
Let the DMAC drivers interpret/parse the sg-list and program it
as strides if the h/w supports it.
If anything, we should make preparation and submission of sg-list
as efficient as possible.
Jassi,

sg_lists describe only a bunch of disjoint buffers. But what if the
DMAC can skip and read the bytes within each of the buffers in
the sg_list? (like TI EDMAC and TI SDMAC)
How can that information be passed to the offload
engine driver from the client?

~Sundaram
Jassi Brar
2011-07-12 12:45:22 UTC
Permalink
Post by Raju, Sundaram
Post by Pillai, Manikandan
-----Original Message-----
Sent: Tuesday, July 12, 2011 4:51 PM
To: Linus Walleij
om;
rnel.org
Post by Raju, Sundaram
Post by Pillai, Manikandan
Subject: Re: [PATCH] dmaengine: add dma_ctrl_cmd to pass buffer stri=
de
Post by Raju, Sundaram
Post by Pillai, Manikandan
configuration
=2Eorg>
com>
Post by Raju, Sundaram
Post by Pillai, Manikandan
1) Striding, in one form or other, is supported by other DMACs as=
well.
Post by Raju, Sundaram
Post by Pillai, Manikandan
=C2=A0 The number will only increase in future.
=C2=A0 Are we to add =C2=A0<VENDOR>_DMA_STRIDE_CONFIG for each ca=
se ?
Post by Raju, Sundaram
Post by Pillai, Manikandan
If we are sure about this and striding will work in a similar way =
on all
Post by Raju, Sundaram
Post by Pillai, Manikandan
then let's have the enum named DMA_STRIDE_CONFIG and move the
passed-in struct to <linux/dmaengine.h) then?
struct dma_stride_config {
=C2=A0 =C2=A0u32 read_bytes;
=C2=A0 =C2=A0u32 skip_bytes;
};
Or something more complex?
Well, I am not sure if striding needs any special treatment at all.
Why not have client drivers prepare and submit sg-list.
Let the DMAC drivers interpret/parse the sg-list and program it
as strides if the h/w supports it.
If anything, we should make preparation and submission of sg-list
as efficient as possible.
Jassi,
sg_lists describe only a bunch of disjoint buffers. But what if the
DMAC can skip and read the bytes within each of the buffers in
the sg_list? (like TI EDMAC and TI SDMAC)
How can that information be passed to the offload
engine driver from the client?
OK, I overlooked.
We do need something new to handle these ultra-fine-grained sg-lists.
But still we shouldn't add SoC specific API to the common sub-systems.

Maybe a new api to pass fixed-format variable-length encoded message
to the DMAC drivers?
Which could be interpreted by DMAC drivers to extract all the needed xf=
er
parameters from the 'header' section and instructions to program the xf=
ers
in the DMAC from the variable length body of the 'message' buffer.
It might sound complicated but we can have helpers to make the job easy=
=2E
Btw, the regular single/sg-list xfers could also be expressed by this m=
ethod.
Raju, Sundaram
2011-07-18 07:51:58 UTC
Permalink
Post by Pillai, Manikandan
-----Original Message-----
Sent: Tuesday, July 12, 2011 6:15 PM
To: Raju, Sundaram
Subject: Re: [PATCH] dmaengine: add dma_ctrl_cmd to pass buffer stride
configuration
Post by Raju, Sundaram
Post by Pillai, Manikandan
-----Original Message-----
Sent: Tuesday, July 12, 2011 4:51 PM
To: Linus Walleij
Subject: Re: [PATCH] dmaengine: add dma_ctrl_cmd to pass buffer stride
configuration
Post by Jassi Brar
1) Striding, in one form or other, is supported by other DMACs as well.
  The number will only increase in future.
  Are we to add  <VENDOR>_DMA_STRIDE_CONFIG for each case ?
If we are sure about this and striding will work in a similar way on all
then let's have the enum named DMA_STRIDE_CONFIG and move the
passed-in struct to <linux/dmaengine.h) then?
struct dma_stride_config {
   u32 read_bytes;
   u32 skip_bytes;
};
Or something more complex?
Well, I am not sure if striding needs any special treatment at all.
Why not have client drivers prepare and submit sg-list.
Let the DMAC drivers interpret/parse the sg-list and program it
as strides if the h/w supports it.
If anything, we should make preparation and submission of sg-list
as efficient as possible.
Jassi,
sg_lists describe only a bunch of disjoint buffers. But what if the
DMAC can skip and read the bytes within each of the buffers in
the sg_list? (like TI EDMAC and TI SDMAC)
How can that information be passed to the offload
engine driver from the client?
OK, I overlooked.
We do need something new to handle these ultra-fine-grained sg-lists.
But still we shouldn't add SoC specific API to the common sub-systems.
Maybe a new api to pass fixed-format variable-length encoded message
to the DMAC drivers?
Which could be interpreted by DMAC drivers to extract all the needed xfer
parameters from the 'header' section and instructions to program the xfers
in the DMAC from the variable length body of the 'message' buffer.
It might sound complicated but we can have helpers to make the job easy.
Btw, the regular single/sg-list xfers could also be expressed by this method.
Do you expect this variable length body of the message to be DMAC
independent? I don't think so. In that case how is this different from what
we have here already?

If it can be DMAC independent, can you illustrate more on how this can
be done? But the point to note is, if this can be made DMAC independent
then the control command we have also can be made DMAC independent
by generalizing
Jassi Brar
2011-07-23 20:35:28 UTC
Permalink
Post by Raju, Sundaram
Post by Jassi Brar
Maybe a new api to pass fixed-format variable-length encoded message
to the DMAC drivers?
Which could be interpreted by DMAC drivers to extract all the needed xfer
parameters from the 'header' section and instructions to program the xfers
in the DMAC from the variable length body of the 'message' buffer.
It might sound complicated but we can have helpers to make the job easy.
Btw, the regular single/sg-list xfers could also be expressed by this method.
Do you expect this variable length body of the message to be DMAC
independent? I don't think so. In that case how is this different from what
we have here already?
Yes, this whould be DMAC independent.
Post by Raju, Sundaram
If it can be DMAC independent, can you illustrate more on how this can
be done? But the point to note is, if this can be made DMAC independent
then the control command we have also can be made DMAC independent
by generalizing the configuration structure passed to it.
The 'header' I suggest, would in fact be a structure body, only an extra pointer
would point to the 'instructions' to convey actual location and sizes
of mico-xfers.
I don't think it is possible to have general definition of such transfers fully
within a structure. If I understand what you ask.

I have just posted an RFC. I kept the terms same so that it is easier
to understand.
Please have a look. You are CC'ed too.

Thanks,
Jassi
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Venkatraman S
2011-09-01 19:05:56 UTC
Permalink
Reuse omap_hsmmc_dma_cleanup even for normal dma teardown in
omap_hsmmc_dma_cb. Consolidate multiple points of dma unmap into a
single location in post_req function, to prevent double unmapping.

Signed-off-by: Venkatraman S <***@ti.com>
---
drivers/mmc/host/omap_hsmmc.c | 20 +++++---------------
1 files changed, 5 insertions(+), 15 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 21e4a79..5b7776c 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -999,7 +999,8 @@ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno)
{
int dma_ch;

- host->data->error = errno;
+ if (host->data)
+ host->data->error = errno;

spin_lock(&host->irq_lock);
dma_ch = host->dma_ch;
@@ -1007,12 +1008,8 @@ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno)
spin_unlock(&host->irq_lock);

if (host->use_dma && dma_ch != -1) {
- dma_unmap_sg(mmc_dev(host->mmc), host->data->sg,
- host->data->sg_len,
- omap_hsmmc_get_dma_dir(host, host->data));
omap_free_dma(dma_ch);
}
- host->data = NULL;
}

/*
@@ -1370,7 +1367,7 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data)
{
struct omap_hsmmc_host *host = cb_data;
struct mmc_data *data;
- int dma_ch, req_in_progress;
+ int req_in_progress;

if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) {
dev_warn(mmc_dev(host->mmc), "unexpected dma status %x\n",
@@ -1394,16 +1391,9 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data)
return;
}

- if (!data->host_cookie)
- dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
- omap_hsmmc_get_dma_dir(host, data));
-
req_in_progress = host->req_in_progress;
- dma_ch = host->dma_ch;
- host->dma_ch = -1;
spin_unlock(&host->irq_lock);
-
- omap_free_dma(dma_ch);
+ omap_hsmmc_dma_cleanup(host, 0);

/* If DMA has finished after TC, complete the request */
if (!req_in_progress) {
@@ -1575,7 +1565,7 @@ static void omap_hsmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq,
struct omap_hsmmc_host *host = mmc_priv(mmc);
struct mmc_data *data = mrq->data;

- if (host->use_dma) {
+ if (data->host_cookie) {
dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
omap_hsmmc_get_dma_dir(host, data));
data->host_cookie = 0;
--
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Kishore Kadiyala
2011-09-06 19:03:28 UTC
Permalink
Post by Venkatraman S
Reuse omap_hsmmc_dma_cleanup even for normal dma teardown in
omap_hsmmc_dma_cb. Consolidate multiple points of dma unmap into a
single location in post_req function, to prevent double unmapping.
---
=A0drivers/mmc/host/omap_hsmmc.c | =A0 20 +++++---------------
=A01 files changed, 5 insertions(+), 15 deletions(-)
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hs=
mmc.c
Post by Venkatraman S
index 21e4a79..5b7776c 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -999,7 +999,8 @@ static void omap_hsmmc_dma_cleanup(struct omap_hs=
mmc_host *host, int errno)
Post by Venkatraman S
=A0{
=A0 =A0 =A0 =A0int dma_ch;
- =A0 =A0 =A0 host->data->error =3D errno;
+ =A0 =A0 =A0 if (host->data)
The condition check above becomes redundant since dma_cleanup is
called during errors in omap_hsmmc_do_irq. Better have this check in
the dma_cb where dma_cleanup is newly added.
Post by Venkatraman S
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 host->data->error =3D errno;
=A0 =A0 =A0 =A0spin_lock(&host->irq_lock);
=A0 =A0 =A0 =A0dma_ch =3D host->dma_ch;
@@ -1007,12 +1008,8 @@ static void omap_hsmmc_dma_cleanup(struct omap=
_hsmmc_host *host, int errno)
Post by Venkatraman S
=A0 =A0 =A0 =A0spin_unlock(&host->irq_lock);
=A0 =A0 =A0 =A0if (host->use_dma && dma_ch !=3D -1) {
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 dma_unmap_sg(mmc_dev(host->mmc), host->=
data->sg,
Post by Venkatraman S
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 host->data->sg_len,
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 omap_hsmmc_get_dma_dir(=
host, host->data));
Post by Venkatraman S
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0omap_free_dma(dma_ch);
=A0 =A0 =A0 =A0}
- =A0 =A0 =A0 host->data =3D NULL;
No need to remove the above one.
Post by Venkatraman S
=A0}
=A0/*
@@ -1370,7 +1367,7 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_s=
tatus, void *cb_data)
Post by Venkatraman S
=A0{
=A0 =A0 =A0 =A0struct omap_hsmmc_host *host =3D cb_data;
=A0 =A0 =A0 =A0struct mmc_data *data;
- =A0 =A0 =A0 int dma_ch, req_in_progress;
+ =A0 =A0 =A0 int req_in_progress;
=A0 =A0 =A0 =A0if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) {
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0dev_warn(mmc_dev(host->mmc), "unexpect=
ed dma status %x\n",
Post by Venkatraman S
@@ -1394,16 +1391,9 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_=
status, void *cb_data)
Post by Venkatraman S
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return;
=A0 =A0 =A0 =A0}
- =A0 =A0 =A0 if (!data->host_cookie)
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 dma_unmap_sg(mmc_dev(host->mmc), data->=
sg, data->sg_len,
Post by Venkatraman S
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0omap_hsmmc_g=
et_dma_dir(host, data));
Post by Venkatraman S
-
=A0 =A0 =A0 =A0req_in_progress =3D host->req_in_progress;
- =A0 =A0 =A0 dma_ch =3D host->dma_ch;
- =A0 =A0 =A0 host->dma_ch =3D -1;
=A0 =A0 =A0 =A0spin_unlock(&host->irq_lock);
-
- =A0 =A0 =A0 omap_free_dma(dma_ch);
+ =A0 =A0 =A0 omap_hsmmc_dma_cleanup(host, 0);
=A0 =A0 =A0 =A0/* If DMA has finished after TC, complete the request =
*/
Post by Venkatraman S
=A0 =A0 =A0 =A0if (!req_in_progress) {
@@ -1575,7 +1565,7 @@ static void omap_hsmmc_post_req(struct mmc_host=
*mmc, struct mmc_request *mrq,
Post by Venkatraman S
=A0 =A0 =A0 =A0struct omap_hsmmc_host *host =3D mmc_priv(mmc);
=A0 =A0 =A0 =A0struct mmc_data *data =3D mrq->data;
- =A0 =A0 =A0 if (host->use_dma) {
Here also , the above conditional check is required.
Post by Venkatraman S
+ =A0 =A0 =A0 if (data->host_cookie) {
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0dma_unmap_sg(mmc_dev(host->mmc), data-=
sg, data->sg_len,
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 omap_hsmmc_ge=
t_dma_dir(host, data));
Post by Venkatraman S
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0data->host_cookie =3D 0;
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-omap"=
in
Post by Venkatraman S
More majordomo info at =A0http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Per Forlin
2011-09-12 19:56:52 UTC
Permalink
Post by Venkatraman S
Reuse omap_hsmmc_dma_cleanup even for normal dma teardown in
omap_hsmmc_dma_cb. Consolidate multiple points of dma unmap into a
single location in post_req function, to prevent double unmapping.
It's optional to use pre_req() and post_req(). The SDIO framework
doesn't utilise these hooks. For instance this wont work together with
SDIO-wlan on the pandaboard.
If pre_req() has been issued it's fine to defer dma_unmap() until
post_req(). If pre_req() is not called the driver should call
dma_unmap() directly.

Regards,
Per
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
S, Venkatraman
2011-09-13 09:20:56 UTC
Permalink
Post by Per Forlin
Post by Venkatraman S
Reuse omap_hsmmc_dma_cleanup even for normal dma teardown in
omap_hsmmc_dma_cb. Consolidate multiple points of dma unmap into a
single location in post_req function, to prevent double unmapping.
It's optional to use pre_req() and post_req(). The SDIO framework
doesn't utilise these hooks. For instance this wont work together with
SDIO-wlan on the pandaboard.
If pre_req() has been issued it's fine to defer dma_unmap() until
post_req(). If pre_req() is not called the driver should call
dma_unmap() directly.
Thanks for the clarification. I'll redo the fix.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
S, Venkatraman
2011-09-14 13:40:42 UTC
Permalink
Post by Per Forlin
Post by Venkatraman S
Reuse omap_hsmmc_dma_cleanup even for normal dma teardown in
omap_hsmmc_dma_cb. Consolidate multiple points of dma unmap into a
single location in post_req function, to prevent double unmapping.
It's optional to use pre_req() and post_req(). The SDIO framework
doesn't utilise these hooks. For instance this wont work together with
SDIO-wlan on the pandaboard.
If pre_req() has been issued it's fine to defer dma_unmap() until
post_req(). If pre_req() is not called the driver should call
dma_unmap() directly.
In that case, can the actual 'request' function just call pre_req and post_req
(at the beginning and at the end), if host_cookie is not set ?
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Per Forlin
2011-09-14 20:55:18 UTC
Permalink
Post by S, Venkatraman
Post by Per Forlin
Post by Venkatraman S
Reuse omap_hsmmc_dma_cleanup even for normal dma teardown in
omap_hsmmc_dma_cb. Consolidate multiple points of dma unmap into a
single location in post_req function, to prevent double unmapping.
It's optional to use pre_req() and post_req(). The SDIO framework
doesn't utilise these hooks. For instance this wont work together with
SDIO-wlan on the pandaboard.
If pre_req() has been issued it's fine to defer dma_unmap() until
post_req(). If pre_req() is not called the driver should call
dma_unmap() directly.
In that case, can the actual 'request' function just call pre_req and post_req
(at the beginning and at the end), if host_cookie is not set ?
Which request() function do your refer to? The mmc_host_ops.request()
returns before the transfer is finished.
Apart from that, I would say yes. It's nice to have the same code path
for valid cookie and invalid cookie scenario.

Note that the host_cookie could be set but with an invalid value.
host driver:
1. validate cookie
2. if invalid cookie call pre_req()
3. run request
4. done -> if (has called pre_req() #2) -> call post_req().

A general fix would be to put this logic in mmc_wait_for_req() in
core.c, but at this level it's not possible to validate the cookie. In
the current implementation the host driver controls the cookie value.

/Per
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Venkatraman S
2011-09-01 19:05:55 UTC
Permalink
The first patch substitutes the dma_cleanup function in place of
the body of the code which does the same thing. The dma unmap
operation is now restricted just to the post_req function.

The second patch minimizes holding spin lock during dma
configuration, where it is not necessary.

Venkatraman S (2):
omap: hsmmc: normalize dma cleanup operations
omap: hsmmc: don't hold spinlock during dma configuration

drivers/mmc/host/omap_hsmmc.c | 22 ++++++----------------
1 files changed, 6 insertions(+), 16 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Venkatraman S
2011-09-01 19:05:57 UTC
Permalink
No need to hold the spinlock during a rather long dma configuration
sequence inside dma callback, which doesn't need it.

Signed-off-by: Venkatraman S <***@ti.com>
---
drivers/mmc/host/omap_hsmmc.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 5b7776c..c5fd413 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1384,10 +1384,10 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data)
data = host->mrq->data;
host->dma_sg_idx++;
if (host->dma_sg_idx < host->dma_len) {
+ spin_unlock(&host->irq_lock);
/* Fire up the next transfer. */
omap_hsmmc_config_dma_params(host, data,
data->sg + host->dma_sg_idx);
- spin_unlock(&host->irq_lock);
return;
}
--
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-12-06 16:49:06 UTC
Permalink
Hi Tony,

This is a trivial cleanup series the removed some useless stuff inside
DTS and force DT by default in an omap2plus_config build.

Patches are based 3.2-rc4 and are available here:
git://gitorious.org/omap-pm/linux.git for_3.3/1_dt_base

Regards,
Benoit


Benoit Cousson (3):
ARM: OMAP2+: kconfig: Enable devicetree by default for OMAP2+ systems
arm/dts: OMAP: Remove bootargs node from board files
ARM: OMAP2+: board-generic: Replace #if defined by #ifdef for consistency

arch/arm/boot/dts/omap3-beagle.dts | 9 ---------
arch/arm/boot/dts/omap4-panda.dts | 9 ---------
arch/arm/boot/dts/omap4-sdp.dts | 9 ---------
arch/arm/mach-omap2/Kconfig | 1 -
arch/arm/mach-omap2/board-generic.c | 8 ++++----
arch/arm/plat-omap/Kconfig | 4 ++++
6 files changed, 8 insertions(+), 32 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-12-06 16:49:07 UTC
Permalink
devicetree will become the mandatory boot method for OMAP2+.
In order to avoid cluttering the OMAP code with #ifdef CONFIG_OF,
select USE_OF by default for every OMAP2+ systems.
Select as well the APPENDED_DTB and ATAG_DTB_COMPAT to allow legacy
boot loader to keep working properly.

Enable PROC_DEVICETREE as well.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Cc: Tony Lindgren <***@atomide.com>
---
arch/arm/mach-omap2/Kconfig | 1 -
arch/arm/plat-omap/Kconfig | 4 ++++
2 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index e1293aa..056a812 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -109,7 +109,6 @@ comment "OMAP Board Type"
config MACH_OMAP_GENERIC
bool "Generic OMAP2+ board"
depends on ARCH_OMAP2PLUS
- select USE_OF
default y
help
Support for generic TI OMAP2+ boards using Flattened Device Tree.
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index aa59f42..74f41dc 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -24,6 +24,10 @@ config ARCH_OMAP2PLUS
select CLKDEV_LOOKUP
select GENERIC_IRQ_CHIP
select OMAP_DM_TIMER
+ select USE_OF
+ select ARM_APPENDED_DTB
+ select ARM_ATAG_DTB_COMPAT
+ select PROC_DEVICETREE
help
"Systems based on OMAP2, OMAP3 or OMAP4"
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Tomi Valkeinen
2011-12-13 13:27:16 UTC
Permalink
Hi,
Post by Benoit Cousson
devicetree will become the mandatory boot method for OMAP2+.
In order to avoid cluttering the OMAP code with #ifdef CONFIG_OF,
select USE_OF by default for every OMAP2+ systems.
Select as well the APPENDED_DTB and ATAG_DTB_COMPAT to allow legacy
boot loader to keep working properly.
APPENDED_DTB sounds a bit dangerous to be enabled by default according
to the config help text.

Tomi
Cousson, Benoit
2011-12-13 13:34:00 UTC
Permalink
Post by Tomi Valkeinen
Hi,
Post by Benoit Cousson
devicetree will become the mandatory boot method for OMAP2+.
In order to avoid cluttering the OMAP code with #ifdef CONFIG_OF,
select USE_OF by default for every OMAP2+ systems.
Select as well the APPENDED_DTB and ATAG_DTB_COMPAT to allow legacy
boot loader to keep working properly.
APPENDED_DTB sounds a bit dangerous to be enabled by default according
to the config help text.
The help is indeed really scary :-)

Tony,
Do we want to keep it by default? Or should we fix the kconfig help?

Regards
Benoit

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Tony Lindgren
2011-12-13 22:38:56 UTC
Permalink
Post by Cousson, Benoit
Post by Tomi Valkeinen
Hi,
Post by Benoit Cousson
devicetree will become the mandatory boot method for OMAP2+.
In order to avoid cluttering the OMAP code with #ifdef CONFIG_OF,
select USE_OF by default for every OMAP2+ systems.
Select as well the APPENDED_DTB and ATAG_DTB_COMPAT to allow legacy
boot loader to keep working properly.
APPENDED_DTB sounds a bit dangerous to be enabled by default according
to the config help text.
The help is indeed really scary :-)
Heh, but it's also true.
Post by Cousson, Benoit
Tony,
Do we want to keep it by default? Or should we fix the kconfig help?
Let's just leave out those two from omap2plus_defconfig then.

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Cousson, Benoit
2011-12-15 16:28:49 UTC
Permalink
Post by Tony Lindgren
Post by Cousson, Benoit
Post by Tomi Valkeinen
Hi,
Post by Benoit Cousson
devicetree will become the mandatory boot method for OMAP2+.
In order to avoid cluttering the OMAP code with #ifdef CONFIG_OF,
select USE_OF by default for every OMAP2+ systems.
Select as well the APPENDED_DTB and ATAG_DTB_COMPAT to allow legacy
boot loader to keep working properly.
APPENDED_DTB sounds a bit dangerous to be enabled by default according
to the config help text.
The help is indeed really scary :-)
Heh, but it's also true.
Post by Cousson, Benoit
Tony,
Do we want to keep it by default? Or should we fix the kconfig help?
Let's just leave out those two from omap2plus_defconfig then.
OK. I'll do that.

Benoit

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Cousson, Benoit
2011-12-16 15:25:40 UTC
Permalink
Hi Tony,
Post by Tony Lindgren
Post by Cousson, Benoit
Post by Tomi Valkeinen
Hi,
Post by Benoit Cousson
devicetree will become the mandatory boot method for OMAP2+.
In order to avoid cluttering the OMAP code with #ifdef CONFIG_OF,
select USE_OF by default for every OMAP2+ systems.
Select as well the APPENDED_DTB and ATAG_DTB_COMPAT to allow legacy
boot loader to keep working properly.
APPENDED_DTB sounds a bit dangerous to be enabled by default according
to the config help text.
The help is indeed really scary :-)
Heh, but it's also true.
Post by Cousson, Benoit
Tony,
Do we want to keep it by default? Or should we fix the kconfig help?
Let's just leave out those two from omap2plus_defconfig then.
Here is the updated version.
Just let me know if you'd like to get the full series re-posted.

Thanks,
Benoit

---
From b33d4be0213ab0c630b87bd3df77035cbb109cd0 Mon Sep 17 00:00:00 2001
From: Benoit Cousson <b-cousson-***@public.gmane.org>
Date: Thu, 1 Dec 2011 10:21:16 +0100
Subject: [PATCH] ARM: OMAP2+: kconfig: Enable devicetree by default for OMAP2+ systems

devicetree will become the mandatory boot method for OMAP2+.
In order to avoid cluttering the OMAP code with #ifdef CONFIG_OF,
select USE_OF by default for every OMAP2+ systems.

Enable PROC_DEVICETREE as well.

Signed-off-by: Benoit Cousson <b-cousson-***@public.gmane.org>
Cc: Tony Lindgren <tony-***@public.gmane.org>
---
arch/arm/mach-omap2/Kconfig | 1 -
arch/arm/plat-omap/Kconfig | 2 ++
2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index b662513..bdd5b68 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -111,7 +111,6 @@ comment "OMAP Board Type"
config MACH_OMAP_GENERIC
bool "Generic OMAP2+ board"
depends on ARCH_OMAP2PLUS
- select USE_OF
default y
help
Support for generic TI OMAP2+ boards using Flattened Device Tree.
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index aa59f42..734009a 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -24,6 +24,8 @@ config ARCH_OMAP2PLUS
select CLKDEV_LOOKUP
select GENERIC_IRQ_CHIP
select OMAP_DM_TIMER
+ select USE_OF
+ select PROC_DEVICETREE
help
"Systems based on OMAP2, OMAP3 or OMAP4"
--
1.7.0.4
Tony Lindgren
2011-12-17 00:20:42 UTC
Permalink
Post by Benoit Cousson
Hi Tony,
Post by Tony Lindgren
Post by Cousson, Benoit
Post by Tomi Valkeinen
Hi,
Post by Benoit Cousson
devicetree will become the mandatory boot method for OMAP2+.
In order to avoid cluttering the OMAP code with #ifdef CONFIG_OF,
select USE_OF by default for every OMAP2+ systems.
Select as well the APPENDED_DTB and ATAG_DTB_COMPAT to allow legacy
boot loader to keep working properly.
APPENDED_DTB sounds a bit dangerous to be enabled by default according
to the config help text.
The help is indeed really scary :-)
Heh, but it's also true.
Post by Cousson, Benoit
Tony,
Do we want to keep it by default? Or should we fix the kconfig help?
Let's just leave out those two from omap2plus_defconfig then.
Here is the updated version.
Just let me know if you'd like to get the full series re-posted.
Thanks applying into dt branch. No need to repost this series.

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Grant Likely
2012-01-04 20:11:11 UTC
Permalink
Post by Benoit Cousson
devicetree will become the mandatory boot method for OMAP2+.
In order to avoid cluttering the OMAP code with #ifdef CONFIG_OF,
select USE_OF by default for every OMAP2+ systems.
Select as well the APPENDED_DTB and ATAG_DTB_COMPAT to allow legacy
boot loader to keep working properly.
Enable PROC_DEVICETREE as well.
---
=A0arch/arm/mach-omap2/Kconfig | =A0 =A01 -
=A0arch/arm/plat-omap/Kconfig =A0| =A0 =A04 ++++
=A02 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfi=
g
Post by Benoit Cousson
index e1293aa..056a812 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -109,7 +109,6 @@ comment "OMAP Board Type"
=A0config MACH_OMAP_GENERIC
=A0 =A0 =A0 =A0bool "Generic OMAP2+ board"
=A0 =A0 =A0 =A0depends on ARCH_OMAP2PLUS
- =A0 =A0 =A0 select USE_OF
=A0 =A0 =A0 =A0default y
=A0 =A0 =A0 =A0help
=A0 =A0 =A0 =A0 =A0Support for generic TI OMAP2+ boards using Flatten=
ed Device Tree.
Post by Benoit Cousson
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index aa59f42..74f41dc 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -24,6 +24,10 @@ config ARCH_OMAP2PLUS
=A0 =A0 =A0 =A0select CLKDEV_LOOKUP
=A0 =A0 =A0 =A0select GENERIC_IRQ_CHIP
=A0 =A0 =A0 =A0select OMAP_DM_TIMER
+ =A0 =A0 =A0 select USE_OF
+ =A0 =A0 =A0 select ARM_APPENDED_DTB
+ =A0 =A0 =A0 select ARM_ATAG_DTB_COMPAT
+ =A0 =A0 =A0 select PROC_DEVICETREE
=A0 =A0 =A0 =A0help
=A0 =A0 =A0 =A0 =A0"Systems based on OMAP2, OMAP3 or OMAP4"
--
1.7.0.4
_______________________________________________
linux-arm-kernel mailing list
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" i=
n
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Cousson, Benoit
2012-01-06 16:37:17 UTC
Permalink
Post by Benoit Cousson
devicetree will become the mandatory boot method for OMAP2+.
In order to avoid cluttering the OMAP code with #ifdef CONFIG_OF,
select USE_OF by default for every OMAP2+ systems.
Select as well the APPENDED_DTB and ATAG_DTB_COMPAT to allow legacy
boot loader to keep working properly.
Enable PROC_DEVICETREE as well.
Thanks for the reviews.

Benoit
Benoit Cousson
2011-12-06 16:49:08 UTC
Permalink
Since 3.2, the CONFIG_ARM_ATAG_DTB_COMPAT config allows
an old bootloader to still use ATAG to provide cmdline.

Remove chosen/bootargs from the DTS board files.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Cc: Grant Likely <***@secretlab.ca>
Cc: Rob Herring <***@calxeda.com>
---
arch/arm/boot/dts/omap3-beagle.dts | 9 ---------
arch/arm/boot/dts/omap4-panda.dts | 9 ---------
arch/arm/boot/dts/omap4-sdp.dts | 9 ---------
3 files changed, 0 insertions(+), 27 deletions(-)

diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts
index 9486be6..9f72cd4 100644
--- a/arch/arm/boot/dts/omap3-beagle.dts
+++ b/arch/arm/boot/dts/omap3-beagle.dts
@@ -13,15 +13,6 @@
model = "TI OMAP3 BeagleBoard";
compatible = "ti,omap3-beagle", "ti,omap3";

- /*
- * Since the initial device tree board file does not create any
- * devices (MMC, network...), the only way to boot is to provide a
- * ramdisk.
- */
- chosen {
- bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug earlyprintk";
- };
-
memory {
device_type = "memory";
reg = <0x80000000 0x20000000>; /* 512 MB */
diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts
index c702657..9755ad5 100644
--- a/arch/arm/boot/dts/omap4-panda.dts
+++ b/arch/arm/boot/dts/omap4-panda.dts
@@ -13,15 +13,6 @@
model = "TI OMAP4 PandaBoard";
compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4";

- /*
- * Since the initial device tree board file does not create any
- * devices (MMC, network...), the only way to boot is to provide a
- * ramdisk.
- */
- chosen {
- bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug";
- };
-
memory {
device_type = "memory";
reg = <0x80000000 0x40000000>; /* 1 GB */
diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts
index 066e28c..63c6b2b 100644
--- a/arch/arm/boot/dts/omap4-sdp.dts
+++ b/arch/arm/boot/dts/omap4-sdp.dts
@@ -13,15 +13,6 @@
model = "TI OMAP4 SDP board";
compatible = "ti,omap4-sdp", "ti,omap4430", "ti,omap4";

- /*
- * Since the initial device tree board file does not create any
- * devices (MMC, network...), the only way to boot is to provide a
- * ramdisk.
- */
- chosen {
- bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug";
- };
-
memory {
device_type = "memory";
reg = <0x80000000 0x40000000>; /* 1 GB */
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Rob Herring
2011-12-06 18:06:48 UTC
Permalink
Benoit,
Post by Benoit Cousson
Since 3.2, the CONFIG_ARM_ATAG_DTB_COMPAT config allows
an old bootloader to still use ATAG to provide cmdline.
Remove chosen/bootargs from the DTS board files.
Acked-by: Rob Herring <***@calxeda.com>

Rob
Post by Benoit Cousson
---
arch/arm/boot/dts/omap3-beagle.dts | 9 ---------
arch/arm/boot/dts/omap4-panda.dts | 9 ---------
arch/arm/boot/dts/omap4-sdp.dts | 9 ---------
3 files changed, 0 insertions(+), 27 deletions(-)
diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts
index 9486be6..9f72cd4 100644
--- a/arch/arm/boot/dts/omap3-beagle.dts
+++ b/arch/arm/boot/dts/omap3-beagle.dts
@@ -13,15 +13,6 @@
model = "TI OMAP3 BeagleBoard";
compatible = "ti,omap3-beagle", "ti,omap3";
- /*
- * Since the initial device tree board file does not create any
- * devices (MMC, network...), the only way to boot is to provide a
- * ramdisk.
- */
- chosen {
- bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug earlyprintk";
- };
-
memory {
device_type = "memory";
reg = <0x80000000 0x20000000>; /* 512 MB */
diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts
index c702657..9755ad5 100644
--- a/arch/arm/boot/dts/omap4-panda.dts
+++ b/arch/arm/boot/dts/omap4-panda.dts
@@ -13,15 +13,6 @@
model = "TI OMAP4 PandaBoard";
compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4";
- /*
- * Since the initial device tree board file does not create any
- * devices (MMC, network...), the only way to boot is to provide a
- * ramdisk.
- */
- chosen {
- bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug";
- };
-
memory {
device_type = "memory";
reg = <0x80000000 0x40000000>; /* 1 GB */
diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts
index 066e28c..63c6b2b 100644
--- a/arch/arm/boot/dts/omap4-sdp.dts
+++ b/arch/arm/boot/dts/omap4-sdp.dts
@@ -13,15 +13,6 @@
model = "TI OMAP4 SDP board";
compatible = "ti,omap4-sdp", "ti,omap4430", "ti,omap4";
- /*
- * Since the initial device tree board file does not create any
- * devices (MMC, network...), the only way to boot is to provide a
- * ramdisk.
- */
- chosen {
- bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug";
- };
-
memory {
device_type = "memory";
reg = <0x80000000 0x40000000>; /* 1 GB */
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Tony Lindgren
2011-12-09 00:55:37 UTC
Permalink
Post by Rob Herring
Benoit,
Post by Benoit Cousson
Since 3.2, the CONFIG_ARM_ATAG_DTB_COMPAT config allows
an old bootloader to still use ATAG to provide cmdline.
Remove chosen/bootargs from the DTS board files.
Thanks applying patches 1 & 2 into omap dt branch.
Still wondering if we should combine patch 3 into
some other cleanup to avoid extra churn..

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Grant Likely
2012-01-04 20:08:19 UTC
Permalink
Post by Benoit Cousson
Since 3.2, the CONFIG_ARM_ATAG_DTB_COMPAT config allows
an old bootloader to still use ATAG to provide cmdline.
Remove chosen/bootargs from the DTS board files.
---
arch/arm/boot/dts/omap3-beagle.dts | 9 ---------
arch/arm/boot/dts/omap4-panda.dts | 9 ---------
arch/arm/boot/dts/omap4-sdp.dts | 9 ---------
3 files changed, 0 insertions(+), 27 deletions(-)
diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts
index 9486be6..9f72cd4 100644
--- a/arch/arm/boot/dts/omap3-beagle.dts
+++ b/arch/arm/boot/dts/omap3-beagle.dts
@@ -13,15 +13,6 @@
model = "TI OMAP3 BeagleBoard";
compatible = "ti,omap3-beagle", "ti,omap3";
- /*
- * Since the initial device tree board file does not create any
- * devices (MMC, network...), the only way to boot is to provide a
- * ramdisk.
- */
- chosen {
- bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug earlyprintk";
- };
-
memory {
device_type = "memory";
reg = <0x80000000 0x20000000>; /* 512 MB */
diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts
index c702657..9755ad5 100644
--- a/arch/arm/boot/dts/omap4-panda.dts
+++ b/arch/arm/boot/dts/omap4-panda.dts
@@ -13,15 +13,6 @@
model = "TI OMAP4 PandaBoard";
compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4";
- /*
- * Since the initial device tree board file does not create any
- * devices (MMC, network...), the only way to boot is to provide a
- * ramdisk.
- */
- chosen {
- bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug";
- };
-
memory {
device_type = "memory";
reg = <0x80000000 0x40000000>; /* 1 GB */
diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts
index 066e28c..63c6b2b 100644
--- a/arch/arm/boot/dts/omap4-sdp.dts
+++ b/arch/arm/boot/dts/omap4-sdp.dts
@@ -13,15 +13,6 @@
model = "TI OMAP4 SDP board";
compatible = "ti,omap4-sdp", "ti,omap4430", "ti,omap4";
- /*
- * Since the initial device tree board file does not create any
- * devices (MMC, network...), the only way to boot is to provide a
- * ramdisk.
- */
- chosen {
- bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug";
- };
-
memory {
device_type = "memory";
reg = <0x80000000 0x40000000>; /* 1 GB */
--
1.7.0.4
_______________________________________________
linux-arm-kernel mailing list
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Benoit Cousson
2011-12-06 16:49:09 UTC
Permalink
The file contains a mix of #ifdef and #if defined().
Replace the #if... by #ifdef.

Signed-off-by: Benoit Cousson <b-***@ti.com>
Cc: Tony Lindgren <***@atomide.com>
---
arch/arm/mach-omap2/board-generic.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index fb55fa3..09f44e0 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -92,7 +92,7 @@ static void __init omap3_init(void)
}
#endif

-#if defined(CONFIG_SOC_OMAP2420)
+#ifdef CONFIG_SOC_OMAP2420
static const char *omap242x_boards_compat[] __initdata = {
"ti,omap2420",
NULL,
@@ -110,7 +110,7 @@ DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)")
MACHINE_END
#endif

-#if defined(CONFIG_SOC_OMAP2430)
+#ifdef CONFIG_SOC_OMAP2430
static const char *omap243x_boards_compat[] __initdata = {
"ti,omap2430",
NULL,
@@ -128,7 +128,7 @@ DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)")
MACHINE_END
#endif

-#if defined(CONFIG_ARCH_OMAP3)
+#ifdef CONFIG_ARCH_OMAP3
static const char *omap3_boards_compat[] __initdata = {
"ti,omap3",
NULL,
@@ -146,7 +146,7 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
MACHINE_END
#endif

-#if defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP4
static const char *omap4_boards_compat[] __initdata = {
"ti,omap4",
NULL,
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Cousson, Benoit
2011-12-20 13:20:11 UTC
Permalink
Hi Tony,

What about that patch?

This is the only one that is missing in lo.
I know it is not a big deal, but it will make things a little bit cleaner.

Thanks,
Benoit
Post by Benoit Cousson
The file contains a mix of #ifdef and #if defined().
Replace the #if... by #ifdef.
---
arch/arm/mach-omap2/board-generic.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index fb55fa3..09f44e0 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -92,7 +92,7 @@ static void __init omap3_init(void)
}
#endif
-#if defined(CONFIG_SOC_OMAP2420)
+#ifdef CONFIG_SOC_OMAP2420
static const char *omap242x_boards_compat[] __initdata = {
"ti,omap2420",
NULL,
@@ -110,7 +110,7 @@ DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)")
MACHINE_END
#endif
-#if defined(CONFIG_SOC_OMAP2430)
+#ifdef CONFIG_SOC_OMAP2430
static const char *omap243x_boards_compat[] __initdata = {
"ti,omap2430",
NULL,
@@ -128,7 +128,7 @@ DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)")
MACHINE_END
#endif
-#if defined(CONFIG_ARCH_OMAP3)
+#ifdef CONFIG_ARCH_OMAP3
static const char *omap3_boards_compat[] __initdata = {
"ti,omap3",
NULL,
@@ -146,7 +146,7 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
MACHINE_END
#endif
-#if defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP4
static const char *omap4_boards_compat[] __initdata = {
"ti,omap4",
NULL,
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Tony Lindgren
2011-12-21 19:19:15 UTC
Permalink
Post by Benoit Cousson
Hi Tony,
What about that patch?
This is the only one that is missing in lo.
I know it is not a big deal, but it will make things a little bit cleaner.
I think we should wait on this one and combine it later on into
some other clean-up patch.

Regards,

Tony
Post by Benoit Cousson
Thanks,
Benoit
Post by Benoit Cousson
The file contains a mix of #ifdef and #if defined().
Replace the #if... by #ifdef.
---
arch/arm/mach-omap2/board-generic.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index fb55fa3..09f44e0 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -92,7 +92,7 @@ static void __init omap3_init(void)
}
#endif
-#if defined(CONFIG_SOC_OMAP2420)
+#ifdef CONFIG_SOC_OMAP2420
static const char *omap242x_boards_compat[] __initdata = {
"ti,omap2420",
NULL,
@@ -110,7 +110,7 @@ DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)")
MACHINE_END
#endif
-#if defined(CONFIG_SOC_OMAP2430)
+#ifdef CONFIG_SOC_OMAP2430
static const char *omap243x_boards_compat[] __initdata = {
"ti,omap2430",
NULL,
@@ -128,7 +128,7 @@ DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)")
MACHINE_END
#endif
-#if defined(CONFIG_ARCH_OMAP3)
+#ifdef CONFIG_ARCH_OMAP3
static const char *omap3_boards_compat[] __initdata = {
"ti,omap3",
NULL,
@@ -146,7 +146,7 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
MACHINE_END
#endif
-#if defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP4
static const char *omap4_boards_compat[] __initdata = {
"ti,omap4",
NULL,
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Venkatraman S
2012-03-15 14:33:34 UTC
Permalink
Chris,
Here are a group of fixes posted by Felipe and Balaji for the
OMAP hsmmc driver in the past few days.
I've rebased them to the lastest mmc-next and posted them
here again. These have also been tested on OMAP4 development platform.

Please feel to apply directly or pull if that's convenient.

The following changes since commit 5f0390f10c0e9c9c504cdbf4af802252628a2490:

mmc: omap_hsmmc: Avoid a regulator voltage change with dt (2012-03-14 11:33:20 -0400)

are available in the git repository at:

git://github.com/svenkatr/linux.git omap-mmc-pending-for-3.4

for you to fetch changes up to a6caaa13374ab72e37f9cb2e4cebfe3d266fbaf3:

mmc: omap4: hsmmc: fix module re-insertion (2012-03-15 19:45:49 +0530)

----------------------------------------------------------------
Balaji T K (5):
mmc: omap: Enable Auto CMD12
mmc: omap: add DDR support to omap_hsmmc
mmc: omap: use runtime put sync in probe error patch
mmc: omap: context save after enabling runtime pm
mmc: omap4: hsmmc: fix module re-insertion

Felipe Balbi (3):
mmc: host: omap_hsmmc: trivial cleanups
mmc: host: omap_hsmmc: make it behave well as a module
mmc: host: omap_hsmmc: convert to module_platform_driver

drivers/mmc/host/omap_hsmmc.c | 203 ++++++++++++++++++++++-----------------------
1 file changed, 98 insertions(+), 105 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Venkatraman S
2012-03-15 14:33:35 UTC
Permalink
From: Balaji T K <***@ti.com>

Enable Auto-CMD12 for multi block read/write on HSMMC
Tested on OMAP4430, OMAP3430 and OMAP2430 SDP

Signed-off-by: Balaji T K <***@ti.com>
---
drivers/mmc/host/omap_hsmmc.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index f29e1a2..b1e9be7 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -85,6 +85,7 @@
#define BRR_ENABLE (1 << 5)
#define DTO_ENABLE (1 << 20)
#define INIT_STREAM (1 << 1)
+#define ACEN_ACMD12 (1 << 2)
#define DP_SELECT (1 << 21)
#define DDIR (1 << 4)
#define DMA_EN 0x1
@@ -115,6 +116,7 @@
#define OMAP_MMC_MAX_CLOCK 52000000
#define DRIVER_NAME "omap_hsmmc"

+#define AUTO_CMD12 (1 << 0) /* Auto CMD12 support */
/*
* One controller can have multiple slots, like on some omap boards using
* omap.c controller driver. Luckily this is not currently done on any known
@@ -175,6 +177,7 @@ struct omap_hsmmc_host {
int reqs_blocked;
int use_reg;
int req_in_progress;
+ unsigned int flags;
struct omap_hsmmc_next next_data;

struct omap_mmc_platform_data *pdata;
@@ -766,6 +769,8 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd,
cmdtype = 0x3;

cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22);
+ if ((host->flags & AUTO_CMD12) && mmc_op_multi(cmd->opcode))
+ cmdreg |= ACEN_ACMD12;

if (data) {
cmdreg |= DP_SELECT | MSBS | BCE;
@@ -837,11 +842,16 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data)
else
data->bytes_xfered = 0;

- if (!data->stop) {
+ if (data->stop && ((!(host->flags & AUTO_CMD12)) || data->error))
+ omap_hsmmc_start_command(host, data->stop, NULL);
+ else {
+ if (data->stop)
+ data->stop->resp[0] = OMAP_HSMMC_READ(host->base,
+ RSP76);
omap_hsmmc_request_done(host, data->mrq);
- return;
}
- omap_hsmmc_start_command(host, data->stop, NULL);
+
+ return;
}

/*
@@ -1826,6 +1836,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
host->mapbase = res->start;
host->base = ioremap(host->mapbase, SZ_4K);
host->power_mode = MMC_POWER_OFF;
+ host->flags = AUTO_CMD12;
host->next_data.cookie = 1;

platform_set_drvdata(pdev, host);
--
1.7.10.rc0.41.gfa678

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Felipe Balbi
2012-03-15 14:54:03 UTC
Permalink
Hi,
Post by Venkatraman S
@@ -766,6 +769,8 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd,
cmdtype = 0x3;
cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22);
+ if ((host->flags & AUTO_CMD12) && mmc_op_multi(cmd->opcode))
This should have braces too.
Post by Venkatraman S
@@ -837,11 +842,16 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data)
else
data->bytes_xfered = 0;
- if (!data->stop) {
+ if (data->stop && ((!(host->flags & AUTO_CMD12)) || data->error))
+ omap_hsmmc_start_command(host, data->stop, NULL);
+ else {
+ if (data->stop)
+ data->stop->resp[0] = OMAP_HSMMC_READ(host->base,
+ RSP76);
omap_hsmmc_request_done(host, data->mrq);
- return;
}
- omap_hsmmc_start_command(host, data->stop, NULL);
+
+ return;
return is unnecessary.
--
balbi
Felipe Balbi
2012-03-15 14:57:51 UTC
Permalink
Post by Venkatraman S
Enable Auto-CMD12 for multi block read/write on HSMMC
Tested on OMAP4430, OMAP3430 and OMAP2430 SDP
BTW, since patches are flowing through you now, they should have your
SoB line.
--
balbi
Venkatraman S
2012-03-15 14:33:37 UTC
Permalink
From: Balaji T K <***@ti.com>

pm_runtime_put_sync instead of autosuspend pm runtime API
because iounmap(host->base) follows immediately.

Reported-by: Rajendra Nayak <***@ti.com>
Signed-off-by: Balaji T K <***@ti.com>
---
drivers/mmc/host/omap_hsmmc.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index db8af43..0f8d34b 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2014,8 +2014,7 @@ err_reg:
err_irq_cd_init:
free_irq(host->irq, host);
err_irq:
- pm_runtime_mark_last_busy(host->dev);
- pm_runtime_put_autosuspend(host->dev);
+ pm_runtime_put_sync(host->dev);
pm_runtime_disable(host->dev);
clk_put(host->fclk);
if (host->got_dbclk) {
--
1.7.10.rc0.41.gfa678

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Venkatraman S
2012-03-15 14:33:36 UTC
Permalink
From: Balaji T K <***@ti.com>

Add Dual data rate support for omap_hsmmc

Signed-off-by: Balaji T K <***@ti.com>
---
drivers/mmc/host/omap_hsmmc.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index b1e9be7..db8af43 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -92,6 +92,7 @@
#define MSBS (1 << 5)
#define BCE (1 << 1)
#define FOUR_BIT (1 << 1)
+#define DDR (1 << 19)
#define DW8 (1 << 5)
#define CC 0x1
#define TC 0x02
@@ -523,6 +524,10 @@ static void omap_hsmmc_set_bus_width(struct omap_hsmmc_host *host)
u32 con;

con = OMAP_HSMMC_READ(host->base, CON);
+ if (ios->timing == MMC_TIMING_UHS_DDR50)
+ con |= DDR; /* configure in DDR mode */
+ else
+ con &= ~DDR;
switch (ios->bus_width) {
case MMC_BUS_WIDTH_8:
OMAP_HSMMC_WRITE(host->base, CON, con | DW8);
--
1.7.10.rc0.41.gfa678

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Venkatraman S
2012-03-15 14:33:39 UTC
Permalink
From: Felipe Balbi <***@ti.com>

a bunch of non-functional cleanups to the omap_hsmmc
driver.

It basically decreases indentation level, drop unneded
dereferences and drop unneded accesses to the platform_device
structure.

Signed-off-by: Felipe Balbi <***@ti.com>
---
drivers/mmc/host/omap_hsmmc.c | 147 ++++++++++++++++++++---------------------
1 file changed, 70 insertions(+), 77 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 9fa2f39..6b30782 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2037,30 +2037,28 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
struct resource *res;

- if (host) {
- pm_runtime_get_sync(host->dev);
- mmc_remove_host(host->mmc);
- if (host->use_reg)
- omap_hsmmc_reg_put(host);
- if (host->pdata->cleanup)
- host->pdata->cleanup(&pdev->dev);
- free_irq(host->irq, host);
- if (mmc_slot(host).card_detect_irq)
- free_irq(mmc_slot(host).card_detect_irq, host);
-
- pm_runtime_put_sync(host->dev);
- pm_runtime_disable(host->dev);
- clk_put(host->fclk);
- if (host->got_dbclk) {
- clk_disable(host->dbclk);
- clk_put(host->dbclk);
- }
+ pm_runtime_get_sync(host->dev);
+ mmc_remove_host(host->mmc);
+ if (host->use_reg)
+ omap_hsmmc_reg_put(host);
+ if (host->pdata->cleanup)
+ host->pdata->cleanup(&pdev->dev);
+ free_irq(host->irq, host);
+ if (mmc_slot(host).card_detect_irq)
+ free_irq(mmc_slot(host).card_detect_irq, host);

- mmc_free_host(host->mmc);
- iounmap(host->base);
- omap_hsmmc_gpio_free(pdev->dev.platform_data);
+ pm_runtime_put_sync(host->dev);
+ pm_runtime_disable(host->dev);
+ clk_put(host->fclk);
+ if (host->got_dbclk) {
+ clk_disable(host->dbclk);
+ clk_put(host->dbclk);
}

+ mmc_free_host(host->mmc);
+ iounmap(host->base);
+ omap_hsmmc_gpio_free(pdev->dev.platform_data);
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res)
release_mem_region(res->start, resource_size(res));
@@ -2073,49 +2071,45 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
static int omap_hsmmc_suspend(struct device *dev)
{
int ret = 0;
- struct platform_device *pdev = to_platform_device(dev);
- struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
+ struct omap_hsmmc_host *host = dev_get_drvdata(dev);

- if (host && host->suspended)
+ if (!host)
return 0;

- if (host) {
- pm_runtime_get_sync(host->dev);
- host->suspended = 1;
- if (host->pdata->suspend) {
- ret = host->pdata->suspend(&pdev->dev,
- host->slot_id);
- if (ret) {
- dev_dbg(mmc_dev(host->mmc),
- "Unable to handle MMC board"
- " level suspend\n");
- host->suspended = 0;
- return ret;
- }
- }
- ret = mmc_suspend_host(host->mmc);
+ if (host && host->suspended)
+ return 0;

+ pm_runtime_get_sync(host->dev);
+ host->suspended = 1;
+ if (host->pdata->suspend) {
+ ret = host->pdata->suspend(dev, host->slot_id);
if (ret) {
+ dev_dbg(dev, "Unable to handle MMC board"
+ " level suspend\n");
host->suspended = 0;
- if (host->pdata->resume) {
- ret = host->pdata->resume(&pdev->dev,
- host->slot_id);
- if (ret)
- dev_dbg(mmc_dev(host->mmc),
- "Unmask interrupt failed\n");
- }
- goto err;
+ return ret;
}
+ }
+ ret = mmc_suspend_host(host->mmc);

- if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) {
- omap_hsmmc_disable_irq(host);
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
+ if (ret) {
+ host->suspended = 0;
+ if (host->pdata->resume) {
+ ret = host->pdata->resume(dev, host->slot_id);
+ if (ret)
+ dev_dbg(dev, "Unmask interrupt failed\n");
}
- if (host->got_dbclk)
- clk_disable(host->dbclk);
+ goto err;
+ }

+ if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) {
+ omap_hsmmc_disable_irq(host);
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
}
+
+ if (host->got_dbclk)
+ clk_disable(host->dbclk);
err:
pm_runtime_put_sync(host->dev);
return ret;
@@ -2125,38 +2119,37 @@ err:
static int omap_hsmmc_resume(struct device *dev)
{
int ret = 0;
- struct platform_device *pdev = to_platform_device(dev);
- struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
+ struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+
+ if (!host)
+ return 0;

if (host && !host->suspended)
return 0;

- if (host) {
- pm_runtime_get_sync(host->dev);
+ pm_runtime_get_sync(host->dev);

- if (host->got_dbclk)
- clk_enable(host->dbclk);
+ if (host->got_dbclk)
+ clk_enable(host->dbclk);

- if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER))
- omap_hsmmc_conf_bus_power(host);
+ if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER))
+ omap_hsmmc_conf_bus_power(host);

- if (host->pdata->resume) {
- ret = host->pdata->resume(&pdev->dev, host->slot_id);
- if (ret)
- dev_dbg(mmc_dev(host->mmc),
- "Unmask interrupt failed\n");
- }
+ if (host->pdata->resume) {
+ ret = host->pdata->resume(dev, host->slot_id);
+ if (ret)
+ dev_dbg(dev, "Unmask interrupt failed\n");
+ }

- omap_hsmmc_protect_card(host);
+ omap_hsmmc_protect_card(host);

- /* Notify the core to resume the host */
- ret = mmc_resume_host(host->mmc);
- if (ret == 0)
- host->suspended = 0;
+ /* Notify the core to resume the host */
+ ret = mmc_resume_host(host->mmc);
+ if (ret == 0)
+ host->suspended = 0;

- pm_runtime_mark_last_busy(host->dev);
- pm_runtime_put_autosuspend(host->dev);
- }
+ pm_runtime_mark_last_busy(host->dev);
+ pm_runtime_put_autosuspend(host->dev);

return ret;

@@ -2173,7 +2166,7 @@ static int omap_hsmmc_runtime_suspend(struct device *dev)

host = platform_get_drvdata(to_platform_device(dev));
omap_hsmmc_context_save(host);
- dev_dbg(mmc_dev(host->mmc), "disabled\n");
+ dev_dbg(dev, "disabled\n");

return 0;
}
@@ -2184,7 +2177,7 @@ static int omap_hsmmc_runtime_resume(struct device *dev)

host = platform_get_drvdata(to_platform_device(dev));
omap_hsmmc_context_restore(host);
- dev_dbg(mmc_dev(host->mmc), "enabled\n");
+ dev_dbg(dev, "enabled\n");

return 0;
}
--
1.7.10.rc0.41.gfa678

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Venkatraman S
2012-03-15 14:33:38 UTC
Permalink
From: Balaji T K <***@ti.com>

call context save api after enabling runtime pm
to make sure register access in context save api happens with clk enabled.

Signed-off-by: Balaji T K <***@ti.com>
---
drivers/mmc/host/omap_hsmmc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 0f8d34b..9fa2f39 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1871,8 +1871,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
goto err1;
}

- omap_hsmmc_context_save(host);
-
if (host->pdata->controller_flags & OMAP_HSMMC_BROKEN_MULTIBLOCK_READ) {
dev_info(&pdev->dev, "multiblock reads disabled due to 35xx erratum 2.1.1.128; MMC read performance may suffer\n");
mmc->caps2 |= MMC_CAP2_NO_MULTI_READ;
@@ -1883,6 +1881,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
pm_runtime_set_autosuspend_delay(host->dev, MMC_AUTOSUSPEND_DELAY);
pm_runtime_use_autosuspend(host->dev);

+ omap_hsmmc_context_save(host);
+
if (cpu_is_omap2430()) {
host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck");
/*
--
1.7.10.rc0.41.gfa678

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Venkatraman S
2012-03-15 14:33:40 UTC
Permalink
From: Felipe Balbi <***@ti.com>

if we put probe() on __init section, that will never
work for multiple module insertions/removals.

In order to make it work properly, move probe to
__devinit section and use platform_driver_register()
instead of platform_driver_probe().

Signed-off-by: Felipe Balbi <***@ti.com>
---
drivers/mmc/host/omap_hsmmc.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 6b30782..67cb63e 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1780,7 +1780,7 @@ static inline struct omap_mmc_platform_data
}
#endif

-static int __init omap_hsmmc_probe(struct platform_device *pdev)
+static int __devinit omap_hsmmc_probe(struct platform_device *pdev)
{
struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;
struct mmc_host *mmc;
@@ -2032,7 +2032,7 @@ err:
return ret;
}

-static int omap_hsmmc_remove(struct platform_device *pdev)
+static int __devexit omap_hsmmc_remove(struct platform_device *pdev)
{
struct omap_hsmmc_host *host = platform_get_drvdata(pdev);
struct resource *res;
@@ -2190,7 +2190,8 @@ static struct dev_pm_ops omap_hsmmc_dev_pm_ops = {
};

static struct platform_driver omap_hsmmc_driver = {
- .remove = omap_hsmmc_remove,
+ .probe = omap_hsmmc_probe,
+ .remove = __devexit_p(omap_hsmmc_remove),
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
@@ -2202,7 +2203,7 @@ static struct platform_driver omap_hsmmc_driver = {
static int __init omap_hsmmc_init(void)
{
/* Register the MMC driver */
- return platform_driver_probe(&omap_hsmmc_driver, omap_hsmmc_probe);
+ return platform_driver_register(&omap_hsmmc_driver);
}

static void __exit omap_hsmmc_cleanup(void)
--
1.7.10.rc0.41.gfa678

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Venkatraman S
2012-03-15 14:33:42 UTC
Permalink
From: Balaji T K <***@ti.com>

OMAP4 and OMAP3 HSMMC IP registers differ by 0x100 offset.
Addng the offset to platform_device resource structure
increments the start address for every insmod operation.
MMC command fails on re-insertion as module due to incorrect register base.
Fix this by updating the ioremap base address only.

Signed-off-by: Balaji T K <***@ti.com>
---
drivers/mmc/host/omap_hsmmc.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 4476b26..f324cf4 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1813,8 +1813,6 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev)
if (res == NULL || irq < 0)
return -ENXIO;

- res->start += pdata->reg_offset;
- res->end += pdata->reg_offset;
res = request_mem_region(res->start, resource_size(res), pdev->name);
if (res == NULL)
return -EBUSY;
@@ -1838,7 +1836,7 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev)
host->dma_ch = -1;
host->irq = irq;
host->slot_id = 0;
- host->mapbase = res->start;
+ host->mapbase = res->start + pdata->reg_offset;
host->base = ioremap(host->mapbase, SZ_4K);
host->power_mode = MMC_POWER_OFF;
host->flags = AUTO_CMD12;
--
1.7.10.rc0.41.gfa678

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Venkatraman S
2012-03-15 14:33:41 UTC
Permalink
From: Felipe Balbi <***@ti.com>

this will delete some boilerplate code, no functional
changes.

Signed-off-by: Felipe Balbi <***@ti.com>
---
drivers/mmc/host/omap_hsmmc.c | 16 +---------------
1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 67cb63e..4476b26 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2200,21 +2200,7 @@ static struct platform_driver omap_hsmmc_driver = {
},
};

-static int __init omap_hsmmc_init(void)
-{
- /* Register the MMC driver */
- return platform_driver_register(&omap_hsmmc_driver);
-}
-
-static void __exit omap_hsmmc_cleanup(void)
-{
- /* Unregister MMC driver */
- platform_driver_unregister(&omap_hsmmc_driver);
-}
-
-module_init(omap_hsmmc_init);
-module_exit(omap_hsmmc_cleanup);
-
+module_platform_driver(omap_hsmmc_driver);
MODULE_DESCRIPTION("OMAP High Speed Multimedia Card driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRIVER_NAME);
--
1.7.10.rc0.41.gfa678

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Loading...