* [patch 1/9] i2c-s3c2410: fix check for being in suspend.
2008-10-31 16:04 [patch 0/9] I2C patches for S3C24XX Ben Dooks
@ 2008-10-31 16:04 ` Ben Dooks
2008-10-31 16:04 ` [patch 2/9] i2c-s3c2410: Use <linux/io.h> over <asm/io.h> Ben Dooks
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ben Dooks @ 2008-10-31 16:04 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA; +Cc: Ben Dooks
[-- Attachment #1: simtec/i2c-fix-sleep-usage.patch --]
[-- Type: text/plain, Size: 2411 bytes --]
As noted by Julia Lawall <julia-dAYI7NvHqcQ@public.gmane.org>, we can never
trigger the check for being in suspend due to the result
of !readl(i2c->regs + S3C2410_IICCON) & S3C2410_IICCON_IRQEN
always being 0.
Add suspend/resume hooks to stop i2c transactions happening
until the driver has been resumed.
Signed-off-by: Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org>
Index: linux.git/drivers/i2c/busses/i2c-s3c2410.c
===================================================================
--- linux.git.orig/drivers/i2c/busses/i2c-s3c2410.c 2008-10-31 15:07:10.000000000 +0000
+++ linux.git/drivers/i2c/busses/i2c-s3c2410.c 2008-10-31 15:14:14.000000000 +0000
@@ -56,6 +56,7 @@ enum s3c24xx_i2c_state {
struct s3c24xx_i2c {
spinlock_t lock;
wait_queue_head_t wait;
+ unsigned int suspended:1;
struct i2c_msg *msg;
unsigned int msg_num;
@@ -507,7 +508,7 @@ static int s3c24xx_i2c_doxfer(struct s3c
unsigned long timeout;
int ret;
- if (!(readl(i2c->regs + S3C2410_IICCON) & S3C2410_IICCON_IRQEN))
+ if (i2c->suspended)
return -EIO;
ret = s3c24xx_i2c_set_master(i2c);
@@ -986,17 +987,26 @@ static int s3c24xx_i2c_remove(struct pla
}
#ifdef CONFIG_PM
+static int s3c24xx_i2c_suspend_late(struct platform_device *dev,
+ pm_message_t msg)
+{
+ struct s3c24xx_i2c *i2c = platform_get_drvdata(dev);
+ i2c->suspended = 1;
+ return 0;
+}
+
static int s3c24xx_i2c_resume(struct platform_device *dev)
{
struct s3c24xx_i2c *i2c = platform_get_drvdata(dev);
- if (i2c != NULL)
- s3c24xx_i2c_init(i2c);
+ i2c->suspended = 0;
+ s3c24xx_i2c_init(i2c);
return 0;
}
#else
+#define s3c24xx_i2c_suspend_late NULL
#define s3c24xx_i2c_resume NULL
#endif
@@ -1005,6 +1015,7 @@ static int s3c24xx_i2c_resume(struct pla
static struct platform_driver s3c2410_i2c_driver = {
.probe = s3c24xx_i2c_probe,
.remove = s3c24xx_i2c_remove,
+ .suspend_late = s3c24xx_i2c_suspend_late,
.resume = s3c24xx_i2c_resume,
.driver = {
.owner = THIS_MODULE,
@@ -1015,6 +1026,7 @@ static struct platform_driver s3c2410_i2
static struct platform_driver s3c2440_i2c_driver = {
.probe = s3c24xx_i2c_probe,
.remove = s3c24xx_i2c_remove,
+ .suspend_late = s3c24xx_i2c_suspend_late,
.resume = s3c24xx_i2c_resume,
.driver = {
.owner = THIS_MODULE,
--
Ben (ben-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 10+ messages in thread* [patch 2/9] i2c-s3c2410: Use <linux/io.h> over <asm/io.h>
2008-10-31 16:04 [patch 0/9] I2C patches for S3C24XX Ben Dooks
2008-10-31 16:04 ` [patch 1/9] i2c-s3c2410: fix check for being in suspend Ben Dooks
@ 2008-10-31 16:04 ` Ben Dooks
2008-10-31 16:04 ` [patch 3/9] i2c-s3c2410: fixup style problems from checkpatch.pl Ben Dooks
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ben Dooks @ 2008-10-31 16:04 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA; +Cc: Ben Dooks
[-- Attachment #1: simtec/s3c64xx/i2c-fix-io-include.patch --]
[-- Type: text/plain, Size: 827 bytes --]
The <linux/io.h> include should be used in prefference
to <asm/io.h>, so replace it.
Signed-off-by: Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org>
Index: linux.git/drivers/i2c/busses/i2c-s3c2410.c
===================================================================
--- linux.git.orig/drivers/i2c/busses/i2c-s3c2410.c 2008-10-30 14:51:00.000000000 +0000
+++ linux.git/drivers/i2c/busses/i2c-s3c2410.c 2008-10-30 14:51:16.000000000 +0000
@@ -34,10 +34,10 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
+#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/irq.h>
-#include <asm/io.h>
#include <mach/regs-gpio.h>
#include <plat/regs-iic.h>
--
Ben (ben-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 10+ messages in thread* [patch 3/9] i2c-s3c2410: fixup style problems from checkpatch.pl
2008-10-31 16:04 [patch 0/9] I2C patches for S3C24XX Ben Dooks
2008-10-31 16:04 ` [patch 1/9] i2c-s3c2410: fix check for being in suspend Ben Dooks
2008-10-31 16:04 ` [patch 2/9] i2c-s3c2410: Use <linux/io.h> over <asm/io.h> Ben Dooks
@ 2008-10-31 16:04 ` Ben Dooks
2008-10-31 16:04 ` [patch 4/9] i2c-s3c2410: use platform data for gpio configuration Ben Dooks
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ben Dooks @ 2008-10-31 16:04 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA; +Cc: Ben Dooks
[-- Attachment #1: simtec/s3c64xx/i2c-fix-checkpatch-problems.patch --]
[-- Type: text/plain, Size: 10104 bytes --]
Fixup the 36 warnings and errors generated from running
checkpatch.pl on the driver. The warnings are too numerous
to be listed here.
Signed-off-by: Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org>
Index: linux.git/drivers/i2c/busses/i2c-s3c2410.c
===================================================================
--- linux.git.orig/drivers/i2c/busses/i2c-s3c2410.c 2008-10-31 11:55:49.000000000 +0000
+++ linux.git/drivers/i2c/busses/i2c-s3c2410.c 2008-10-31 11:55:50.000000000 +0000
@@ -110,7 +110,8 @@ static inline int s3c24xx_i2c_is2440(str
* the default if there is none
*/
-static inline struct s3c2410_platform_i2c *s3c24xx_i2c_get_platformdata(struct device *dev)
+static inline struct s3c2410_platform_i2c *
+s3c24xx_i2c_get_platformdata(struct device *dev)
{
if (dev->platform_data != NULL)
return (struct s3c2410_platform_i2c *)dev->platform_data;
@@ -130,7 +131,7 @@ static inline void s3c24xx_i2c_master_co
i2c->msg_ptr = 0;
i2c->msg = NULL;
- i2c->msg_idx ++;
+ i2c->msg_idx++;
i2c->msg_num = 0;
if (ret)
i2c->msg_idx = ret;
@@ -141,19 +142,17 @@ static inline void s3c24xx_i2c_master_co
static inline void s3c24xx_i2c_disable_ack(struct s3c24xx_i2c *i2c)
{
unsigned long tmp;
-
+
tmp = readl(i2c->regs + S3C2410_IICCON);
writel(tmp & ~S3C2410_IICCON_ACKEN, i2c->regs + S3C2410_IICCON);
-
}
static inline void s3c24xx_i2c_enable_ack(struct s3c24xx_i2c *i2c)
{
unsigned long tmp;
-
+
tmp = readl(i2c->regs + S3C2410_IICCON);
writel(tmp | S3C2410_IICCON_ACKEN, i2c->regs + S3C2410_IICCON);
-
}
/* irq enable/disable functions */
@@ -161,7 +160,7 @@ static inline void s3c24xx_i2c_enable_ac
static inline void s3c24xx_i2c_disable_irq(struct s3c24xx_i2c *i2c)
{
unsigned long tmp;
-
+
tmp = readl(i2c->regs + S3C2410_IICCON);
writel(tmp & ~S3C2410_IICCON_IRQEN, i2c->regs + S3C2410_IICCON);
}
@@ -169,7 +168,7 @@ static inline void s3c24xx_i2c_disable_i
static inline void s3c24xx_i2c_enable_irq(struct s3c24xx_i2c *i2c)
{
unsigned long tmp;
-
+
tmp = readl(i2c->regs + S3C2410_IICCON);
writel(tmp | S3C2410_IICCON_IRQEN, i2c->regs + S3C2410_IICCON);
}
@@ -177,10 +176,10 @@ static inline void s3c24xx_i2c_enable_ir
/* s3c24xx_i2c_message_start
*
- * put the start of a message onto the bus
+ * put the start of a message onto the bus
*/
-static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
+static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
struct i2c_msg *msg)
{
unsigned int addr = (msg->addr & 0x7f) << 1;
@@ -199,15 +198,15 @@ static void s3c24xx_i2c_message_start(st
if (msg->flags & I2C_M_REV_DIR_ADDR)
addr ^= 1;
- // todo - check for wether ack wanted or not
+ /* todo - check for wether ack wanted or not */
s3c24xx_i2c_enable_ack(i2c);
iiccon = readl(i2c->regs + S3C2410_IICCON);
writel(stat, i2c->regs + S3C2410_IICSTAT);
-
+
dev_dbg(i2c->dev, "START: %08lx to IICSTAT, %02x to DS\n", stat, addr);
writeb(addr, i2c->regs + S3C2410_IICDS);
-
+
/* delay here to ensure the data byte has gotten onto the bus
* before the transaction is started */
@@ -215,8 +214,8 @@ static void s3c24xx_i2c_message_start(st
dev_dbg(i2c->dev, "iiccon, %08lx\n", iiccon);
writel(iiccon, i2c->regs + S3C2410_IICCON);
-
- stat |= S3C2410_IICSTAT_START;
+
+ stat |= S3C2410_IICSTAT_START;
writel(stat, i2c->regs + S3C2410_IICSTAT);
}
@@ -227,11 +226,11 @@ static inline void s3c24xx_i2c_stop(stru
dev_dbg(i2c->dev, "STOP\n");
/* stop the transfer */
- iicstat &= ~ S3C2410_IICSTAT_START;
+ iicstat &= ~S3C2410_IICSTAT_START;
writel(iicstat, i2c->regs + S3C2410_IICSTAT);
-
+
i2c->state = STATE_STOP;
-
+
s3c24xx_i2c_master_complete(i2c, ret);
s3c24xx_i2c_disable_irq(i2c);
}
@@ -241,7 +240,7 @@ static inline void s3c24xx_i2c_stop(stru
/* is_lastmsg()
*
- * returns TRUE if the current message is the last in the set
+ * returns TRUE if the current message is the last in the set
*/
static inline int is_lastmsg(struct s3c24xx_i2c *i2c)
@@ -289,14 +288,14 @@ static int i2s_s3c_irq_nextbyte(struct s
case STATE_STOP:
dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__);
- s3c24xx_i2c_disable_irq(i2c);
+ s3c24xx_i2c_disable_irq(i2c);
goto out_ack;
case STATE_START:
/* last thing we did was send a start condition on the
* bus, or started a new i2c message
*/
-
+
if (iicstat & S3C2410_IICSTAT_LASTBIT &&
!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
/* ack was not received... */
@@ -322,7 +321,7 @@ static int i2s_s3c_irq_nextbyte(struct s
if (i2c->state == STATE_READ)
goto prepare_read;
- /* fall through to the write state, as we will need to
+ /* fall through to the write state, as we will need to
* send a byte as well */
case STATE_WRITE:
@@ -339,7 +338,7 @@ static int i2s_s3c_irq_nextbyte(struct s
}
}
- retry_write:
+ retry_write:
if (!is_msgend(i2c)) {
byte = i2c->msg->buf[i2c->msg_ptr++];
@@ -359,9 +358,9 @@ static int i2s_s3c_irq_nextbyte(struct s
dev_dbg(i2c->dev, "WRITE: Next Message\n");
i2c->msg_ptr = 0;
- i2c->msg_idx ++;
+ i2c->msg_idx++;
i2c->msg++;
-
+
/* check to see if we need to do another message */
if (i2c->msg->flags & I2C_M_NOSTART) {
@@ -375,7 +374,6 @@ static int i2s_s3c_irq_nextbyte(struct s
goto retry_write;
} else {
-
/* send the new start */
s3c24xx_i2c_message_start(i2c, i2c->msg);
i2c->state = STATE_START;
@@ -389,7 +387,7 @@ static int i2s_s3c_irq_nextbyte(struct s
break;
case STATE_READ:
- /* we have a byte of data in the data register, do
+ /* we have a byte of data in the data register, do
* something with it, and then work out wether we are
* going to do any more read/write
*/
@@ -397,13 +395,13 @@ static int i2s_s3c_irq_nextbyte(struct s
byte = readb(i2c->regs + S3C2410_IICDS);
i2c->msg->buf[i2c->msg_ptr++] = byte;
- prepare_read:
+ prepare_read:
if (is_msglast(i2c)) {
/* last byte of buffer */
if (is_lastmsg(i2c))
s3c24xx_i2c_disable_ack(i2c);
-
+
} else if (is_msgend(i2c)) {
/* ok, we've read the entire buffer, see if there
* is anything else we need to do */
@@ -429,7 +427,7 @@ static int i2s_s3c_irq_nextbyte(struct s
/* acknowlegde the IRQ and get back on with the work */
out_ack:
- tmp = readl(i2c->regs + S3C2410_IICCON);
+ tmp = readl(i2c->regs + S3C2410_IICCON);
tmp &= ~S3C2410_IICCON_IRQPEND;
writel(tmp, i2c->regs + S3C2410_IICCON);
out:
@@ -450,19 +448,19 @@ static irqreturn_t s3c24xx_i2c_irq(int i
status = readl(i2c->regs + S3C2410_IICSTAT);
if (status & S3C2410_IICSTAT_ARBITR) {
- // deal with arbitration loss
+ /* deal with arbitration loss */
dev_err(i2c->dev, "deal with arbitration loss\n");
}
if (i2c->state == STATE_IDLE) {
dev_dbg(i2c->dev, "IRQ: error i2c->state == IDLE\n");
- tmp = readl(i2c->regs + S3C2410_IICCON);
+ tmp = readl(i2c->regs + S3C2410_IICCON);
tmp &= ~S3C2410_IICCON_IRQPEND;
writel(tmp, i2c->regs + S3C2410_IICCON);
goto out;
}
-
+
/* pretty much this leaves us with the fact that we've
* transmitted or received whatever byte we last sent */
@@ -485,7 +483,7 @@ static int s3c24xx_i2c_set_master(struct
while (timeout-- > 0) {
iicstat = readl(i2c->regs + S3C2410_IICSTAT);
-
+
if (!(iicstat & S3C2410_IICSTAT_BUSBUSY))
return 0;
@@ -503,7 +501,8 @@ static int s3c24xx_i2c_set_master(struct
* this starts an i2c transfer
*/
-static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, struct i2c_msg *msgs, int num)
+static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
+ struct i2c_msg *msgs, int num)
{
unsigned long timeout;
int ret;
@@ -529,12 +528,12 @@ static int s3c24xx_i2c_doxfer(struct s3c
s3c24xx_i2c_enable_irq(i2c);
s3c24xx_i2c_message_start(i2c, msgs);
spin_unlock_irq(&i2c->lock);
-
+
timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
ret = i2c->msg_idx;
- /* having these next two as dev_err() makes life very
+ /* having these next two as dev_err() makes life very
* noisy when doing an i2cdetect */
if (timeout == 0)
@@ -643,7 +642,7 @@ static inline int freq_acceptable(unsign
{
int diff = freq - wanted;
- return (diff >= -2 && diff <= 2);
+ return diff >= -2 && diff <= 2;
}
/* s3c24xx_i2c_clockrate
@@ -666,7 +665,7 @@ static int s3c24xx_i2c_clockrate(struct
pdata = s3c24xx_i2c_get_platformdata(i2c->adap.dev.parent);
clkin /= 1000; /* clkin now in KHz */
-
+
dev_dbg(i2c->dev, "pdata %p, freq %lu %lu..%lu\n",
pdata, pdata->bus_freq, pdata->min_freq, pdata->max_freq);
@@ -774,7 +773,7 @@ static inline void s3c24xx_i2c_deregiste
/* s3c24xx_i2c_init
*
- * initialise the controller, set the IO lines and frequency
+ * initialise the controller, set the IO lines and frequency
*/
static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
@@ -793,7 +792,7 @@ static int s3c24xx_i2c_init(struct s3c24
s3c2410_gpio_cfgpin(S3C2410_GPE14, S3C2410_GPE14_IICSCL);
/* write slave address */
-
+
writeb(pdata->slave_addr, i2c->regs + S3C2410_IICADD);
dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr);
@@ -878,7 +877,8 @@ static int s3c24xx_i2c_probe(struct plat
goto err_ioarea;
}
- dev_dbg(&pdev->dev, "registers %p (%p, %p)\n", i2c->regs, i2c->ioarea, res);
+ dev_dbg(&pdev->dev, "registers %p (%p, %p)\n",
+ i2c->regs, i2c->ioarea, res);
/* setup info block for the i2c core */
@@ -892,7 +892,7 @@ static int s3c24xx_i2c_probe(struct plat
goto err_iomap;
/* find the IRQ for this unit (note, this relies on the init call to
- * ensure no current IRQs pending
+ * ensure no current IRQs pending
*/
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -911,7 +911,7 @@ static int s3c24xx_i2c_probe(struct plat
}
i2c->irq = res;
-
+
dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res,
(unsigned long)res->start);
--
Ben (ben-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 10+ messages in thread* [patch 4/9] i2c-s3c2410: use platform data for gpio configuration
2008-10-31 16:04 [patch 0/9] I2C patches for S3C24XX Ben Dooks
` (2 preceding siblings ...)
2008-10-31 16:04 ` [patch 3/9] i2c-s3c2410: fixup style problems from checkpatch.pl Ben Dooks
@ 2008-10-31 16:04 ` Ben Dooks
2008-10-31 16:04 ` [patch 5/9] i2c-s3c2410: Add ARCH_S3C64XX to allowed archs Ben Dooks
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ben Dooks @ 2008-10-31 16:04 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA; +Cc: Ben Dooks
[-- Attachment #1: simtec/s3c64xx/i2c-remove-gpio-config.patch --]
[-- Type: text/plain, Size: 1501 bytes --]
Add a callback to set the gpio configuration for the
i2c device instead of a set include. This also allows
the remvoal of the machine gpio and hardware files.
Signed-off-by: Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org>
Index: linux.git/drivers/i2c/busses/i2c-s3c2410.c
===================================================================
--- linux.git.orig/drivers/i2c/busses/i2c-s3c2410.c 2008-10-31 11:55:50.000000000 +0000
+++ linux.git/drivers/i2c/busses/i2c-s3c2410.c 2008-10-31 11:55:54.000000000 +0000
@@ -36,10 +36,8 @@
#include <linux/cpufreq.h>
#include <linux/io.h>
-#include <mach/hardware.h>
#include <asm/irq.h>
-#include <mach/regs-gpio.h>
#include <plat/regs-iic.h>
#include <plat/iic.h>
@@ -490,9 +488,6 @@ static int s3c24xx_i2c_set_master(struct
msleep(1);
}
- dev_dbg(i2c->dev, "timeout: GPEDAT is %08x\n",
- __raw_readl(S3C2410_GPEDAT));
-
return -ETIMEDOUT;
}
@@ -784,12 +779,12 @@ static int s3c24xx_i2c_init(struct s3c24
/* get the plafrom data */
- pdata = s3c24xx_i2c_get_platformdata(i2c->adap.dev.parent);
+ pdata = s3c24xx_i2c_get_platformdata(i2c->dev);
/* inititalise the gpio */
- s3c2410_gpio_cfgpin(S3C2410_GPE15, S3C2410_GPE15_IICSDA);
- s3c2410_gpio_cfgpin(S3C2410_GPE14, S3C2410_GPE14_IICSCL);
+ if (pdata->cfg_gpio)
+ pdata->cfg_gpio(to_platform_device(i2c->dev));
/* write slave address */
--
Ben (ben-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 10+ messages in thread* [patch 5/9] i2c-s3c2410: Add ARCH_S3C64XX to allowed archs
2008-10-31 16:04 [patch 0/9] I2C patches for S3C24XX Ben Dooks
` (3 preceding siblings ...)
2008-10-31 16:04 ` [patch 4/9] i2c-s3c2410: use platform data for gpio configuration Ben Dooks
@ 2008-10-31 16:04 ` Ben Dooks
2008-10-31 16:04 ` [patch 6/9] i2c-s3c2410: remove default platform data Ben Dooks
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ben Dooks @ 2008-10-31 16:04 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA; +Cc: Ben Dooks
[-- Attachment #1: simtec/s3c64xx/i2c-allow-s3c64xx-build.patch --]
[-- Type: text/plain, Size: 1089 bytes --]
The i2c-s3c2410 driver should be able to support the
ARCH_S3C64XX as well as the ARCH_S3C2410.
Signed-off-by: Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org>
Index: linux.git/drivers/i2c/busses/Kconfig
===================================================================
--- linux.git.orig/drivers/i2c/busses/Kconfig 2008-10-30 15:28:48.000000000 +0000
+++ linux.git/drivers/i2c/busses/Kconfig 2008-10-30 15:29:42.000000000 +0000
@@ -455,11 +455,12 @@ config I2C_PXA_SLAVE
I2C bus.
config I2C_S3C2410
- tristate "S3C2410 I2C Driver"
- depends on ARCH_S3C2410
+ tristate "Samsung SoC I2C Driver (S3C24XX and S3C64XX series)"
+ depends on ARCH_S3C2410 || ARCH_S3C64XX
help
Say Y here to include support for I2C controller in the
- Samsung S3C2410 based System-on-Chip devices.
+ Samsung S3C based System-on-Chip devices such as the S3C2410,
+ S3C2440, S3C2442, S3C2443 and S3C6410.
config I2C_SH7760
tristate "Renesas SH7760 I2C Controller"
--
Ben (ben-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 10+ messages in thread* [patch 6/9] i2c-s3c2410: remove default platform data.
2008-10-31 16:04 [patch 0/9] I2C patches for S3C24XX Ben Dooks
` (4 preceding siblings ...)
2008-10-31 16:04 ` [patch 5/9] i2c-s3c2410: Add ARCH_S3C64XX to allowed archs Ben Dooks
@ 2008-10-31 16:04 ` Ben Dooks
2008-10-31 16:04 ` [patch 7/9] i2c-s3c2410: Allow more than one i2c-s3c2410 adapter Ben Dooks
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Ben Dooks @ 2008-10-31 16:04 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA; +Cc: Ben Dooks
[-- Attachment #1: simtec/s3c64xx/i2c-remove-default-platdata.patch --]
[-- Type: text/plain, Size: 2940 bytes --]
The platform data should now always be present when the device
is initialised, so we can remove the default platform data in
the driver.
All the device initialisation points in the board specific code
should already have been changed to initialise this as necessary.
Signed-off-by: Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org>
Index: linux.git/drivers/i2c/busses/i2c-s3c2410.c
===================================================================
--- linux.git.orig/drivers/i2c/busses/i2c-s3c2410.c 2008-10-31 11:55:54.000000000 +0000
+++ linux.git/drivers/i2c/busses/i2c-s3c2410.c 2008-10-31 11:56:08.000000000 +0000
@@ -78,16 +78,7 @@ struct s3c24xx_i2c {
#endif
};
-/* default platform data to use if not supplied in the platform_device
-*/
-
-static struct s3c2410_platform_i2c s3c24xx_i2c_default_platform = {
- .flags = 0,
- .slave_addr = 0x10,
- .bus_freq = 100*1000,
- .max_freq = 400*1000,
- .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
-};
+/* default platform data removed, dev should always carry data. */
/* s3c24xx_i2c_is2440()
*
@@ -101,22 +92,6 @@ static inline int s3c24xx_i2c_is2440(str
return !strcmp(pdev->name, "s3c2440-i2c");
}
-
-/* s3c24xx_i2c_get_platformdata
- *
- * get the platform data associated with the given device, or return
- * the default if there is none
-*/
-
-static inline struct s3c2410_platform_i2c *
-s3c24xx_i2c_get_platformdata(struct device *dev)
-{
- if (dev->platform_data != NULL)
- return (struct s3c2410_platform_i2c *)dev->platform_data;
-
- return &s3c24xx_i2c_default_platform;
-}
-
/* s3c24xx_i2c_master_complete
*
* complete the message and wake up the caller, using the given return code,
@@ -649,7 +624,7 @@ static inline int freq_acceptable(unsign
static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
{
- struct s3c2410_platform_i2c *pdata;
+ struct s3c2410_platform_i2c *pdata = i2c->dev->platform_data;
unsigned long clkin = clk_get_rate(i2c->clk);
unsigned int divs, div1;
u32 iiccon;
@@ -657,8 +632,6 @@ static int s3c24xx_i2c_clockrate(struct
int start, end;
i2c->clkrate = clkin;
-
- pdata = s3c24xx_i2c_get_platformdata(i2c->adap.dev.parent);
clkin /= 1000; /* clkin now in KHz */
dev_dbg(i2c->dev, "pdata %p, freq %lu %lu..%lu\n",
@@ -779,7 +752,7 @@ static int s3c24xx_i2c_init(struct s3c24
/* get the plafrom data */
- pdata = s3c24xx_i2c_get_platformdata(i2c->dev);
+ pdata = i2c->dev->platform_data;
/* inititalise the gpio */
@@ -830,7 +803,11 @@ static int s3c24xx_i2c_probe(struct plat
struct resource *res;
int ret;
- pdata = s3c24xx_i2c_get_platformdata(&pdev->dev);
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ dev_err(&pdev->dev, "no platform data\n");
+ return -EINVAL;
+ }
/* find the clock and enable it */
--
Ben (ben-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 10+ messages in thread* [patch 7/9] i2c-s3c2410: Allow more than one i2c-s3c2410 adapter
2008-10-31 16:04 [patch 0/9] I2C patches for S3C24XX Ben Dooks
` (5 preceding siblings ...)
2008-10-31 16:04 ` [patch 6/9] i2c-s3c2410: remove default platform data Ben Dooks
@ 2008-10-31 16:04 ` Ben Dooks
2008-10-31 16:04 ` [patch 8/9] S3C: Add i2c1 device definition Ben Dooks
2008-10-31 16:04 ` [patch 9/9] i2c-s3c2410: change IRQ to be plain integer Ben Dooks
8 siblings, 0 replies; 10+ messages in thread
From: Ben Dooks @ 2008-10-31 16:04 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA; +Cc: Ben Dooks
[-- Attachment #1: simtec/s3c64xx/i2c-allow-multiple-instances.patch --]
[-- Type: text/plain, Size: 2340 bytes --]
Newer SoCs such as the S3C6410 have 2 instances of this i2c
controller block in and thus require the ability to create
two seperate busses from this.
Signed-off-by: Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org>
Index: linux.git/drivers/i2c/busses/i2c-s3c2410.c
===================================================================
--- linux.git.orig/drivers/i2c/busses/i2c-s3c2410.c 2008-10-31 11:56:08.000000000 +0000
+++ linux.git/drivers/i2c/busses/i2c-s3c2410.c 2008-10-31 11:56:12.000000000 +0000
@@ -560,19 +560,6 @@ static const struct i2c_algorithm s3c24x
.functionality = s3c24xx_i2c_func,
};
-static struct s3c24xx_i2c s3c24xx_i2c = {
- .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_i2c.lock),
- .wait = __WAIT_QUEUE_HEAD_INITIALIZER(s3c24xx_i2c.wait),
- .tx_setup = 50,
- .adap = {
- .name = "s3c2410-i2c",
- .owner = THIS_MODULE,
- .algo = &s3c24xx_i2c_algorithm,
- .retries = 2,
- .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- },
-};
-
/* s3c24xx_i2c_calcdivisor
*
* return the divisor settings for a given frequency
@@ -798,7 +785,7 @@ static int s3c24xx_i2c_init(struct s3c24
static int s3c24xx_i2c_probe(struct platform_device *pdev)
{
- struct s3c24xx_i2c *i2c = &s3c24xx_i2c;
+ struct s3c24xx_i2c *i2c;
struct s3c2410_platform_i2c *pdata;
struct resource *res;
int ret;
@@ -809,6 +796,22 @@ static int s3c24xx_i2c_probe(struct plat
return -EINVAL;
}
+ i2c = kzalloc(sizeof(struct s3c24xx_i2c), GFP_KERNEL);
+ if (!i2c) {
+ dev_err(&pdev->dev, "no memory for state\n");
+ return -ENOMEM;
+ }
+
+ strlcpy(i2c->adap.name, "s3c2410-i2c", sizeof(i2c->adap.name));
+ i2c->adap.owner = THIS_MODULE;
+ i2c->adap.algo = &s3c24xx_i2c_algorithm;
+ i2c->adap.retries = 2;
+ i2c->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+ i2c->tx_setup = 50;
+
+ spin_lock_init(&i2c->lock);
+ init_waitqueue_head(&i2c->wait);
+
/* find the clock and enable it */
i2c->dev = &pdev->dev;
@@ -930,6 +933,7 @@ static int s3c24xx_i2c_probe(struct plat
clk_put(i2c->clk);
err_noclk:
+ kfree(i2c);
return ret;
}
@@ -954,6 +958,7 @@ static int s3c24xx_i2c_remove(struct pla
release_resource(i2c->ioarea);
kfree(i2c->ioarea);
+ kfree(i2c);
return 0;
}
--
Ben (ben-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 10+ messages in thread* [patch 8/9] S3C: Add i2c1 device definition
2008-10-31 16:04 [patch 0/9] I2C patches for S3C24XX Ben Dooks
` (6 preceding siblings ...)
2008-10-31 16:04 ` [patch 7/9] i2c-s3c2410: Allow more than one i2c-s3c2410 adapter Ben Dooks
@ 2008-10-31 16:04 ` Ben Dooks
2008-10-31 16:04 ` [patch 9/9] i2c-s3c2410: change IRQ to be plain integer Ben Dooks
8 siblings, 0 replies; 10+ messages in thread
From: Ben Dooks @ 2008-10-31 16:04 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA; +Cc: Ben Dooks
[-- Attachment #1: simtec/s3c64xx/i2c-add-second-i2c-bus.patch --]
[-- Type: text/plain, Size: 7598 bytes --]
Add device definition and support functions for the
second i2c device (i2c1). If this is selected, the first
i2c bus will become index 0 instead of index -1.
Signed-off-by: Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org>
Index: linux.git/arch/arm/plat-s3c/dev-i2c1.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux.git/arch/arm/plat-s3c/dev-i2c1.c 2008-10-31 00:06:44.000000000 +0000
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-s3c/dev-i2c1.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben-Y5A6D6n0/KfQXOPxS62xeg@public.gmane.org>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for i2c device 1
+ *
+ * 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC1,
+ .end = S3C_PA_IIC1 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC1,
+ .end = IRQ_IIC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c1 = {
+ .name = "s3c2410-i2c",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .resource = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data1 __initdata = {
+ .flags = 0,
+ .bus_num = 1,
+ .slave_addr = 0x10,
+ .bus_freq = 100*1000,
+ .max_freq = 400*1000,
+ .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
+};
+
+void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd)
+ pd = &default_i2c_data1;
+
+ npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c1_cfg_gpio;
+
+ s3c_device_i2c1.dev.platform_data = npd;
+}
Index: linux.git/arch/arm/mach-s3c6400/include/mach/map.h
===================================================================
--- linux.git.orig/arch/arm/mach-s3c6400/include/mach/map.h 2008-10-31 00:00:24.000000000 +0000
+++ linux.git/arch/arm/mach-s3c6400/include/mach/map.h 2008-10-31 00:00:36.000000000 +0000
@@ -41,6 +41,7 @@
#define S3C64XX_PA_SYSCON (0x7E00F000)
#define S3C64XX_PA_TIMER (0x7F006000)
#define S3C64XX_PA_IIC0 (0x7F004000)
+#define S3C64XX_PA_IIC1 (0x7F00F000)
#define S3C64XX_PA_GPIO (0x7F008000)
#define S3C64XX_VA_GPIO S3C_ADDR(0x00500000)
@@ -60,5 +61,6 @@
#define S3C_PA_HSMMC1 S3C64XX_PA_HSMMC1
#define S3C_PA_HSMMC2 S3C64XX_PA_HSMMC2
#define S3C_PA_IIC S3C64XX_PA_IIC0
+#define S3C_PA_IIC1 S3C64XX_PA_IIC1
#endif /* __ASM_ARCH_6400_MAP_H */
Index: linux.git/arch/arm/plat-s3c/Kconfig
===================================================================
--- linux.git.orig/arch/arm/plat-s3c/Kconfig 2008-10-31 00:00:24.000000000 +0000
+++ linux.git/arch/arm/plat-s3c/Kconfig 2008-10-31 00:00:36.000000000 +0000
@@ -160,3 +160,9 @@ config S3C_DEV_HSMMC1
depends on PLAT_S3C
help
Compile in platform device definitions for HSMMC channel 1
+
+config S3C_DEV_I2C1
+ bool
+ depends on PLAT_S3C
+ help
+ Compile in platform device definitions for I2C channel 1
Index: linux.git/arch/arm/plat-s3c/Makefile
===================================================================
--- linux.git.orig/arch/arm/plat-s3c/Makefile 2008-10-31 00:00:24.000000000 +0000
+++ linux.git/arch/arm/plat-s3c/Makefile 2008-10-31 00:00:36.000000000 +0000
@@ -23,3 +23,4 @@ obj-y += gpio-config.o
obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o
obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o
obj-y += dev-i2c0.o
+obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
Index: linux.git/arch/arm/plat-s3c/dev-i2c0.c
===================================================================
--- linux.git.orig/arch/arm/plat-s3c/dev-i2c0.c 2008-10-31 00:00:24.000000000 +0000
+++ linux.git/arch/arm/plat-s3c/dev-i2c0.c 2008-10-31 00:07:05.000000000 +0000
@@ -37,12 +37,16 @@ static struct resource s3c_i2c_resource[
struct platform_device s3c_device_i2c0 = {
.name = "s3c2410-i2c",
+#ifdef CONFIG_S3C_DEV_I2C1
+ .id = 0,
+#else
.id = -1,
+#endif
.num_resources = ARRAY_SIZE(s3c_i2c_resource),
.resource = s3c_i2c_resource,
};
-struct s3c2410_platform_i2c default_i2c_data __initdata = {
+static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
.flags = 0,
.slave_addr = 0x10,
.bus_freq = 100*1000,
@@ -55,7 +59,7 @@ void __init s3c_i2c0_set_platdata(struct
struct s3c2410_platform_i2c *npd;
if (!pd)
- pd = &default_i2c_data;
+ pd = &default_i2c_data0;
npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
if (!npd)
Index: linux.git/arch/arm/plat-s3c/include/plat/iic.h
===================================================================
--- linux.git.orig/arch/arm/plat-s3c/include/plat/iic.h 2008-10-31 00:00:24.000000000 +0000
+++ linux.git/arch/arm/plat-s3c/include/plat/iic.h 2008-10-31 00:00:36.000000000 +0000
@@ -48,8 +48,10 @@ struct s3c2410_platform_i2c {
* as the driver will no longer carry defaults.
*/
extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c);
/* defined by architecture to configure gpio */
extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c1_cfg_gpio(struct platform_device *dev);
#endif /* __ASM_ARCH_IIC_H */
Index: linux.git/arch/arm/plat-s3c/include/plat/devs.h
===================================================================
--- linux.git.orig/arch/arm/plat-s3c/include/plat/devs.h 2008-10-31 00:00:24.000000000 +0000
+++ linux.git/arch/arm/plat-s3c/include/plat/devs.h 2008-10-31 00:00:36.000000000 +0000
@@ -28,6 +28,7 @@ extern struct platform_device s3c_device
extern struct platform_device s3c_device_lcd;
extern struct platform_device s3c_device_wdt;
extern struct platform_device s3c_device_i2c0;
+extern struct platform_device s3c_device_i2c1;
extern struct platform_device s3c_device_iis;
extern struct platform_device s3c_device_rtc;
extern struct platform_device s3c_device_adc;
Index: linux.git/arch/arm/plat-s3c64xx/include/plat/irqs.h
===================================================================
--- linux.git.orig/arch/arm/plat-s3c64xx/include/plat/irqs.h 2008-10-31 00:03:34.000000000 +0000
+++ linux.git/arch/arm/plat-s3c64xx/include/plat/irqs.h 2008-10-31 00:13:33.000000000 +0000
@@ -70,6 +70,7 @@
#define IRQ_CAMIF_C S3C64XX_IRQ_VIC0(3)
#define IRQ_CAMIF_P S3C64XX_IRQ_VIC0(4)
#define IRQ_CAMIF_MC S3C64XX_IRQ_VIC0(5)
+#define IRQ_S3C6410_IIC1 S3C64XX_IRQ_VIC0(5)
#define IRQ_S3C6410_IIS S3C64XX_IRQ_VIC0(6)
#define IRQ_S3C6400_CAMIF_MP S3C64XX_IRQ_VIC0(6)
#define IRQ_CAMIF_WE_C S3C64XX_IRQ_VIC0(7)
@@ -144,6 +145,10 @@
#define IRQ_TIMER3 S3C64XX_TIMER_IRQ(3)
#define IRQ_TIMER4 S3C64XX_TIMER_IRQ(4)
+/* compatibility for device defines */
+
+#define IRQ_IIC1 IRQ_S3C6410_IIC1
+
/* Since the IRQ_EINT(x) are a linear mapping on current s3c64xx series
* we just defined them as an IRQ_EINT(x) macro from S3C_IRQ_EINT_BASE
* which we place after the pair of VICs. */
--
Ben (ben-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 10+ messages in thread* [patch 9/9] i2c-s3c2410: change IRQ to be plain integer.
2008-10-31 16:04 [patch 0/9] I2C patches for S3C24XX Ben Dooks
` (7 preceding siblings ...)
2008-10-31 16:04 ` [patch 8/9] S3C: Add i2c1 device definition Ben Dooks
@ 2008-10-31 16:04 ` Ben Dooks
8 siblings, 0 replies; 10+ messages in thread
From: Ben Dooks @ 2008-10-31 16:04 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA; +Cc: Ben Dooks
[-- Attachment #1: simtec/s3c64xx/i2c-improve-irq-code.patch --]
[-- Type: text/plain, Size: 2385 bytes --]
Change the code to use a plain integer as the holder
for the IRQ for the device and use platform_get_irq()
to find it.
This makes the code slightly neater, and easier to get
the IRQ number.
Signed-off-by: Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org>
Index: linux.git/drivers/i2c/busses/i2c-s3c2410.c
===================================================================
--- linux.git.orig/drivers/i2c/busses/i2c-s3c2410.c 2008-10-31 11:56:12.000000000 +0000
+++ linux.git/drivers/i2c/busses/i2c-s3c2410.c 2008-10-31 11:56:18.000000000 +0000
@@ -62,6 +62,7 @@ struct s3c24xx_i2c {
unsigned int msg_ptr;
unsigned int tx_setup;
+ unsigned int irq;
enum s3c24xx_i2c_state state;
unsigned long clkrate;
@@ -69,7 +70,6 @@ struct s3c24xx_i2c {
void __iomem *regs;
struct clk *clk;
struct device *dev;
- struct resource *irq;
struct resource *ioarea;
struct i2c_adapter adap;
@@ -870,26 +870,20 @@ static int s3c24xx_i2c_probe(struct plat
* ensure no current IRQs pending
*/
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res == NULL) {
+ i2c->irq = ret = platform_get_irq(pdev, 0);
+ if (ret <= 0) {
dev_err(&pdev->dev, "cannot find IRQ\n");
- ret = -ENOENT;
goto err_iomap;
}
- ret = request_irq(res->start, s3c24xx_i2c_irq, IRQF_DISABLED,
- pdev->name, i2c);
+ ret = request_irq(i2c->irq, s3c24xx_i2c_irq, IRQF_DISABLED,
+ dev_name(&pdev->dev), i2c);
if (ret != 0) {
- dev_err(&pdev->dev, "cannot claim IRQ\n");
+ dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
goto err_iomap;
}
- i2c->irq = res;
-
- dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res,
- (unsigned long)res->start);
-
ret = s3c24xx_i2c_register_cpufreq(i2c);
if (ret < 0) {
dev_err(&pdev->dev, "failed to register cpufreq notifier\n");
@@ -919,7 +913,7 @@ static int s3c24xx_i2c_probe(struct plat
s3c24xx_i2c_deregister_cpufreq(i2c);
err_irq:
- free_irq(i2c->irq->start, i2c);
+ free_irq(i2c->irq, i2c);
err_iomap:
iounmap(i2c->regs);
@@ -949,7 +943,7 @@ static int s3c24xx_i2c_remove(struct pla
s3c24xx_i2c_deregister_cpufreq(i2c);
i2c_del_adapter(&i2c->adap);
- free_irq(i2c->irq->start, i2c);
+ free_irq(i2c->irq, i2c);
clk_disable(i2c->clk);
clk_put(i2c->clk);
--
Ben (ben-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 10+ messages in thread