forked from Minki/linux
cb64babf9e
Second set of OMAP PRCM cleanups for 3.8. These patches remove the use of omap_prcm_get_reset_sources() from the OMAP watchdog driver, and remove mach-omap2/prcm.c and plat-omap/include/plat/prcm.h. Basic test logs for this branch on top of Tony's cleanup-prcm branch at commit7fc54fd308
are here: http://www.pwsan.com/omap/testlogs/prcm_cleanup_b_3.8/20121108151646/ However, cleanup-prcm at7fc54fd3
does not include some fixes that are needed for a successful test. With several reverts, fixes, and workarounds applied, the following test logs were obtained: http://www.pwsan.com/omap/testlogs/TEST_prcm_cleanup_b_3.8/20121108151930/ which indicate that the series tests cleanly. This second pull request updates one of the patches which broke with rmk's allnoconfigs, and also updates the tag description to indicate that7fc54fd3
is building cleanly here. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJQoY0GAAoJEBvUPslcq6Vza0MQAI0idVoOclIHCC63tpc58YWA BpD5OLg4yRu0RUFS1CI/Fq5d+9PfYUspgaWja3TTgUy0EHRDVUUFRaxJdpWdl2NF gX7BCuhnQenznTbCE80nEmxvsh7U/dfvs+JYUK2PriypU61f1+TnSu9ZxTRvDJOx vbo1cfsioVcLfnBPSDSQVJ1fufbafklpeQkDNeRI8UDsCVeXwnxhNsXB3utoJMf0 5gaDaCdRBoimkLnAaLi41OnHYC7IbNCnl/VX0i/xffROsINfL7LDkBPfUOnR5vle jTCV49UEB/P5ekk2cvKKj8IOQZdimiCppWMLit6DObX7LbltTKuXx6T0PclgxQ14 hhav5O+f8NYA4yDAY/xxPlTvShMr8rQcYV6pg1G1OgD+dcq7cbbWNJAvbUJ03hH8 dqZ+ypLYkazb3Mm5XtpFr47gkoaFnCQbgZLXpjJ8+L01aGNrF2L6aE789So1N81+ X1s0ENjRxzDLNcqwxqhcoph0YQe7GlyiviYb7ev25MTSC3/TjrupTViZbKocZmLt Ad9m4SOktbHthAw0jdA48vOmPiSvmYzFiqzMhz/ryeNbyyV6rRxe5w4JUjPzHPxc U7NraSGIAzpqM3EKEp7Rb0yOfh6sGzML/FH9bS25+Rv37yKW0huc6ENIRgatZpY2 blLzsxaKfQgLeqKT82mj =tS2z -----END PGP SIGNATURE----- Merge tag 'omap-for-v3.8/cleanup-prcm-part2-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/cleanup From Tony Lindgren <tony@atomide.com>: More PRCM cleanups via Paul Walmsley <paul@pwsan.com>: Second set of OMAP PRCM cleanups for 3.8. These patches remove the use of omap_prcm_get_reset_sources() from the OMAP watchdog driver, and remove mach-omap2/prcm.c and plat-omap/include/plat/prcm.h. Basic test logs for this branch on top of Tony's cleanup-prcm branch at commit7fc54fd308
are here: http://www.pwsan.com/omap/testlogs/prcm_cleanup_b_3.8/20121108151646/ However, cleanup-prcm at7fc54fd3
does not include some fixes that are needed for a successful test. With several reverts, fixes, and workarounds applied, the following test logs were obtained: http://www.pwsan.com/omap/testlogs/TEST_prcm_cleanup_b_3.8/20121108151930/ which indicate that the series tests cleanly. This second pull request updates one of the patches which broke with rmk's allnoconfigs, and also updates the tag description to indicate that7fc54fd3
is building cleanly here. * tag 'omap-for-v3.8/cleanup-prcm-part2-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: (27 commits) ARM: OMAP2: Fix compillation error in cm_common ARM: OMAP2+: PRCM: remove obsolete prcm.[ch] ARM: OMAP2+: hwmod: call to _omap4_disable_module() should use the SoC-specific call ARM: OMAP2+: PRCM: consolidate PRCM-related timeout macros ARM: OMAP2+: PRCM: split and relocate the PRM/CM globals setup ARM: OMAP2+: PRCM: remove omap2_cm_wait_idlest() ARM: OMAP2+: CM/clock: convert _omap2_module_wait_ready() to use SoC-independent CM functions ARM: OMAP2xxx: APLL/CM: convert to use omap2_cm_wait_module_ready() ARM: OMAP2+: board files: use SoC-specific system restart functions ARM: OMAP2+: PRCM: create SoC-specific chip restart functions ARM: OMAP2xxx: clock: move virt_prcm_set code into clkt2xxx_virt_prcm_set.c ARM: OMAP2xxx: clock: remove global 'dclk' variable ARM: OMAP2/3: PRM: add SoC reset functions (using the CORE DPLL method) ARM: OMAP2+: common: remove mach-omap2/common.c globals and map_common_io code ARM: OMAP2+: PRCM: remove omap_prcm_get_reset_sources() watchdog: OMAP: use standard GETBOOTSTATUS interface; use platform_data fn ptr ARM: OMAP2+: WDT: move init; add read_reset_sources pdata function pointer ARM: OMAP1: CGRM: fix omap1_get_reset_sources() return type ARM: OMAP2+: PRM: create PRM reset source API for the watchdog timer driver ARM: OMAP1: create read_reset_sources() function (for initial use by watchdog) ... Conflicts: arch/arm/mach-omap2/cm33xx.c arch/arm/mach-omap2/io.c arch/arm/mach-omap2/prm_common.c Signed-off-by: Arnd Bergmann <arnd@arndb.de>
168 lines
4.2 KiB
C
168 lines
4.2 KiB
C
/*
|
|
* Helper module for board specific I2C bus registration
|
|
*
|
|
* Copyright (C) 2009 Nokia Corporation.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
|
* 02110-1301 USA
|
|
*
|
|
*/
|
|
|
|
#include "soc.h"
|
|
#include "omap_hwmod.h"
|
|
#include "omap_device.h"
|
|
|
|
#include "prm.h"
|
|
#include "common.h"
|
|
#include "mux.h"
|
|
#include "i2c.h"
|
|
|
|
/* In register I2C_CON, Bit 15 is the I2C enable bit */
|
|
#define I2C_EN BIT(15)
|
|
#define OMAP2_I2C_CON_OFFSET 0x24
|
|
#define OMAP4_I2C_CON_OFFSET 0xA4
|
|
|
|
#define MAX_OMAP_I2C_HWMOD_NAME_LEN 16
|
|
|
|
static void __init omap2_i2c_mux_pins(int bus_id)
|
|
{
|
|
char mux_name[sizeof("i2c2_scl.i2c2_scl")];
|
|
|
|
/* First I2C bus is not muxable */
|
|
if (bus_id == 1)
|
|
return;
|
|
|
|
sprintf(mux_name, "i2c%i_scl.i2c%i_scl", bus_id, bus_id);
|
|
omap_mux_init_signal(mux_name, OMAP_PIN_INPUT);
|
|
sprintf(mux_name, "i2c%i_sda.i2c%i_sda", bus_id, bus_id);
|
|
omap_mux_init_signal(mux_name, OMAP_PIN_INPUT);
|
|
}
|
|
|
|
/**
|
|
* omap_i2c_reset - reset the omap i2c module.
|
|
* @oh: struct omap_hwmod *
|
|
*
|
|
* The i2c moudle in omap2, omap3 had a special sequence to reset. The
|
|
* sequence is:
|
|
* - Disable the I2C.
|
|
* - Write to SOFTRESET bit.
|
|
* - Enable the I2C.
|
|
* - Poll on the RESETDONE bit.
|
|
* The sequence is implemented in below function. This is called for 2420,
|
|
* 2430 and omap3.
|
|
*/
|
|
int omap_i2c_reset(struct omap_hwmod *oh)
|
|
{
|
|
u32 v;
|
|
u16 i2c_con;
|
|
int c = 0;
|
|
|
|
if (oh->class->rev == OMAP_I2C_IP_VERSION_2) {
|
|
i2c_con = OMAP4_I2C_CON_OFFSET;
|
|
} else if (oh->class->rev == OMAP_I2C_IP_VERSION_1) {
|
|
i2c_con = OMAP2_I2C_CON_OFFSET;
|
|
} else {
|
|
WARN(1, "Cannot reset I2C block %s: unsupported revision\n",
|
|
oh->name);
|
|
return -EINVAL;
|
|
}
|
|
|
|
/* Disable I2C */
|
|
v = omap_hwmod_read(oh, i2c_con);
|
|
v &= ~I2C_EN;
|
|
omap_hwmod_write(v, oh, i2c_con);
|
|
|
|
/* Write to the SOFTRESET bit */
|
|
omap_hwmod_softreset(oh);
|
|
|
|
/* Enable I2C */
|
|
v = omap_hwmod_read(oh, i2c_con);
|
|
v |= I2C_EN;
|
|
omap_hwmod_write(v, oh, i2c_con);
|
|
|
|
/* Poll on RESETDONE bit */
|
|
omap_test_timeout((omap_hwmod_read(oh,
|
|
oh->class->sysc->syss_offs)
|
|
& SYSS_RESETDONE_MASK),
|
|
MAX_MODULE_SOFTRESET_WAIT, c);
|
|
|
|
if (c == MAX_MODULE_SOFTRESET_WAIT)
|
|
pr_warning("%s: %s: softreset failed (waited %d usec)\n",
|
|
__func__, oh->name, MAX_MODULE_SOFTRESET_WAIT);
|
|
else
|
|
pr_debug("%s: %s: softreset in %d usec\n", __func__,
|
|
oh->name, c);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int __init omap_i2c_nr_ports(void)
|
|
{
|
|
int ports = 0;
|
|
|
|
if (cpu_is_omap24xx())
|
|
ports = 2;
|
|
else if (cpu_is_omap34xx())
|
|
ports = 3;
|
|
else if (cpu_is_omap44xx())
|
|
ports = 4;
|
|
return ports;
|
|
}
|
|
|
|
static const char name[] = "omap_i2c";
|
|
|
|
int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *i2c_pdata,
|
|
int bus_id)
|
|
{
|
|
int l;
|
|
struct omap_hwmod *oh;
|
|
struct platform_device *pdev;
|
|
char oh_name[MAX_OMAP_I2C_HWMOD_NAME_LEN];
|
|
struct omap_i2c_bus_platform_data *pdata;
|
|
struct omap_i2c_dev_attr *dev_attr;
|
|
|
|
if (bus_id > omap_i2c_nr_ports())
|
|
return -EINVAL;
|
|
|
|
omap2_i2c_mux_pins(bus_id);
|
|
|
|
l = snprintf(oh_name, MAX_OMAP_I2C_HWMOD_NAME_LEN, "i2c%d", bus_id);
|
|
WARN(l >= MAX_OMAP_I2C_HWMOD_NAME_LEN,
|
|
"String buffer overflow in I2C%d device setup\n", bus_id);
|
|
oh = omap_hwmod_lookup(oh_name);
|
|
if (!oh) {
|
|
pr_err("Could not look up %s\n", oh_name);
|
|
return -EEXIST;
|
|
}
|
|
|
|
pdata = i2c_pdata;
|
|
/*
|
|
* pass the hwmod class's CPU-specific knowledge of I2C IP revision in
|
|
* use, and functionality implementation flags, up to the OMAP I2C
|
|
* driver via platform data
|
|
*/
|
|
pdata->rev = oh->class->rev;
|
|
|
|
dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr;
|
|
pdata->flags = dev_attr->flags;
|
|
|
|
pdev = omap_device_build(name, bus_id, oh, pdata,
|
|
sizeof(struct omap_i2c_bus_platform_data),
|
|
NULL, 0, 0);
|
|
WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name);
|
|
|
|
return PTR_RET(pdev);
|
|
}
|
|
|