* Re: StorCenter Help?
From: Jon Loeliger @ 2008-01-11 23:25 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <fa686aa40801111520m3b9c3ea6rc7ee38519dcc9a4b@mail.gmail.com>
So, like, the other day "Grant Likely" mumbled:
>
> Since you're getting absolutely no output after uncompression it
> probably means that you're failing in the boot wrapper...
Or not getting to the boot wrapper...
> which means mmu is off, and the serial port is already set up by u-boot.
>
> You should be able to add direct writes to the uart fifo register from
> within the bootwrapper code to see how far you get in the progress.
Tried that. Didn't work at all.
I think I have some variant of BAT setup failure or so.
jdl
^ permalink raw reply
* Re: StorCenter Help?
From: Grant Likely @ 2008-01-11 23:30 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
In-Reply-To: <E1JDTFP-0007OE-MM@jdl.com>
On 1/11/08, Jon Loeliger <jdl@jdl.com> wrote:
> So, like, the other day "Grant Likely" mumbled:
> >
> > Since you're getting absolutely no output after uncompression it
> > probably means that you're failing in the boot wrapper...
>
> Or not getting to the boot wrapper...
Hmm, yet it boots a regular uImage?
> > which means mmu is off, and the serial port is already set up by u-boot.
> >
> > You should be able to add direct writes to the uart fifo register from
> > within the bootwrapper code to see how far you get in the progress.
>
> Tried that. Didn't work at all.
>
> I think I have some variant of BAT setup failure or so.
weird... Can you get *any* custom code to run *at all*? Even if it's
just a loop that writes a char to the serial port?
>
> jdl
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Please pull powerpc.git merge branch
From: Paul Mackerras @ 2008-01-12 0:09 UTC (permalink / raw)
To: torvalds; +Cc: linuxppc-dev
Linus,
Please do
git pull \
git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc.git merge
to get two more bug fixes for powerpc, as listed below.
Thanks,
Paul.
arch/powerpc/kernel/prom_init.c | 39 ++++++++++++++++++++++++++
arch/powerpc/mm/slb.c | 8 +++++
arch/powerpc/platforms/pseries/hotplug-cpu.c | 2 +
arch/powerpc/platforms/pseries/lpar.c | 1 +
include/asm-powerpc/mmu-hash64.h | 1 +
5 files changed, 51 insertions(+), 0 deletions(-)
commit 473980a99316c0e788bca50996375a2815124ce1
Author: Michael Neuling <mikey@neuling.org>
Date: Fri Jan 11 14:02:47 2008 +1100
[POWERPC] Fix CPU hotplug when using the SLB shadow buffer
Before we register the SLB shadow buffer, we need to invalidate the
entries in the buffer, otherwise we can end up stale entries from when
we previously offlined the CPU.
This does this invalidate as well as unregistering the buffer with
PHYP before we offline the cpu. Tested and fixes crashes seen on
970MP (thanks to tonyb) and POWER5.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
commit 6f4347c969674ed45de7d08d4b26d6326a95b959
Author: Olaf Hering <olaf@aepfle.de>
Date: Thu Jan 10 01:06:08 2008 +1100
[POWERPC] efika: add phy-handle property for fec_mpc52xx
The new network driver fec_mpc52xx will not work on efika because the
firmware does not provide all required properties.
http://www.powerdeveloper.org/asset/by-id/46 has a Forth script to
create more properties. But only the phy stuff is required to get a
working network.
This should go into the kernel because its appearently
impossible to boot the script via tftp and then load the real boot
binary (yaboot or zimage).
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
^ permalink raw reply
* Re: [PATCH 0/2] [PPC 4xx] L2-cache synchronization for ppc44x
From: Benjamin Herrenschmidt @ 2008-01-12 1:52 UTC (permalink / raw)
To: Eugene Surovegin; +Cc: linuxppc-dev, sr, dzu
In-Reply-To: <20080111223831.GA2947@gate.ebshome.net>
On Fri, 2008-01-11 at 14:38 -0800, Eugene Surovegin wrote:
> On Sat, Jan 12, 2008 at 09:05:35AM +1100, Benjamin Herrenschmidt wrote:
> >
> > > > The s/w synchronization algorithms proposed in my patches has no LL PLB
> > > > limitations as opposed to h/w snooping, but, probably, this is not the best
> > > > way of how it might be implemented. Even though with these patches the h/w
> > > > accelerated RAID starts to operate correctly (with L2-cache enabled) there is
> > > > a performance degradation (induced by loops in the L2-cache synchronization
> > > > routines) observed in the most cases. So, as a result, there is no benefit
> > > > from using L2-cache for these, RAID, cases at all.
> > >
> > > Thanks a lot for explanation, Yuri. I'd never imagine they were so
> > > stupid to make new chips with such behaviour.
> >
> > Indeed. Now the question is do we want to make that configurable by the
> > platform so it can select whether to enable snooping, or use this
> > mechanism (in which case we can disable snooping on the L2) ?
>
> I don't think we should panish platforms with sane L2 caches, because
> there are some brain-dead ones.
I agree, which is why I'm thinking about making it some kind of explicit
thing that a give platform would call from it's setup_arch() callbacks
to turn on manual L2 sycnhronization.
> > Another option would be to make the dma_ops smart enough to know whether
> > a given device is on the snooped portion of the bus, which would be
> > easier to do after I merge 32 and 64 bits DMA ops, so we get the ability
> > to change the dma-ops per bus or per device even.
> >
> > What do you guys think ?
>
> I like the idea of having smart DMA routines with different
> per-bus/device behaviour.
That would be longer term. When I merge the dma ops, I'll look into a
way to provide 44x specific DMA ops that handle that case, and then a
way for devices to be tagged (maybe via the device-tree) on whether they
are on an L2 coherent or non-L2 coherent segment of the bus.
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH 1/5] Warp Base Platform
From: Stephen Rothwell @ 2008-01-12 2:40 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev
In-Reply-To: <4787FE23.7010201@pikatech.com>
[-- Attachment #1: Type: text/plain, Size: 452 bytes --]
Hi Sean,
On Fri, 11 Jan 2008 18:39:15 -0500 Sean MacLennan <smaclennan@pikatech.com> wrote:
>
> +++ arch/powerpc/platforms/44x/warp-nand.c 2008-01-11 18:04:10.000000000 -0500
> @@ -0,0 +1,85 @@
You need a copyright/license notice.
The only other concern I have left is the extern in the C file, but that
can be dealt with later.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* [PATCH 19 2/5] Modify several rtc drivers to use the alias names list property of i2c
From: Jon Smirl @ 2008-01-12 2:47 UTC (permalink / raw)
To: i2c, linuxppc-dev, linux-kernel
In-Reply-To: <20080112024737.7023.61680.stgit@terra.home>
This patch modifies the ds1307, ds1374, and rs5c372 i2c drivers to support
device tree names using the new i2c mod alias support
Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
---
arch/powerpc/sysdev/fsl_soc.c | 44 ++++-----------------------------
drivers/rtc/rtc-ds1307.c | 18 +++++++++++++
drivers/rtc/rtc-ds1374.c | 7 +++++
drivers/rtc/rtc-m41t80.c | 55 ++++++++++++++++++++++++++++-------------
drivers/rtc/rtc-rs5c372.c | 14 ++++++++++
5 files changed, 81 insertions(+), 57 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 3ace747..94e5c73 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -320,48 +320,12 @@ arch_initcall(gfar_of_init);
#ifdef CONFIG_I2C_BOARDINFO
#include <linux/i2c.h>
-struct i2c_driver_device {
- char *of_device;
- char *i2c_driver;
- char *i2c_type;
-};
-
-static struct i2c_driver_device i2c_devices[] __initdata = {
- {"ricoh,rs5c372a", "rtc-rs5c372", "rs5c372a",},
- {"ricoh,rs5c372b", "rtc-rs5c372", "rs5c372b",},
- {"ricoh,rv5c386", "rtc-rs5c372", "rv5c386",},
- {"ricoh,rv5c387a", "rtc-rs5c372", "rv5c387a",},
- {"dallas,ds1307", "rtc-ds1307", "ds1307",},
- {"dallas,ds1337", "rtc-ds1307", "ds1337",},
- {"dallas,ds1338", "rtc-ds1307", "ds1338",},
- {"dallas,ds1339", "rtc-ds1307", "ds1339",},
- {"dallas,ds1340", "rtc-ds1307", "ds1340",},
- {"stm,m41t00", "rtc-ds1307", "m41t00"},
- {"dallas,ds1374", "rtc-ds1374", "rtc-ds1374",},
-};
-
-static int __init of_find_i2c_driver(struct device_node *node,
- struct i2c_board_info *info)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
- if (!of_device_is_compatible(node, i2c_devices[i].of_device))
- continue;
- if (strlcpy(info->driver_name, i2c_devices[i].i2c_driver,
- KOBJ_NAME_LEN) >= KOBJ_NAME_LEN ||
- strlcpy(info->type, i2c_devices[i].i2c_type,
- I2C_NAME_SIZE) >= I2C_NAME_SIZE)
- return -ENOMEM;
- return 0;
- }
- return -ENODEV;
-}
static void __init of_register_i2c_devices(struct device_node *adap_node,
int bus_num)
{
struct device_node *node = NULL;
+ const char *compatible;
while ((node = of_get_next_child(adap_node, node))) {
struct i2c_board_info info = {};
@@ -378,8 +342,12 @@ static void __init of_register_i2c_devices(struct device_node *adap_node,
if (info.irq == NO_IRQ)
info.irq = -1;
- if (of_find_i2c_driver(node, &info) < 0)
+ compatible = of_get_property(node, "compatible", &len);
+ if (!compatible) {
+ printk(KERN_WARNING "i2c-mpc.c: invalid entry, missing compatible attribute\n");
continue;
+ }
+ strncpy(info.type, compatible, sizeof(info.type));
info.addr = *addr;
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 9b0eab9..d4874ff 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -139,6 +139,17 @@ static inline const struct chip_desc *find_chip(const char *s)
return NULL;
}
+static struct i2c_device_id ds1307_id[] = {
+ OF_I2C_ID("dallas,ds1307", ds_1307)
+ OF_I2C_ID("dallas,ds1337", ds_1337)
+ OF_I2C_ID("dallas,ds1338", ds_1338)
+ OF_I2C_ID("dallas,ds1339", ds_1339)
+ OF_I2C_ID("dallas,ds1340", ds_1340)
+ OF_I2C_ID("stm,m41t00", m41t00)
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, ds1307_id);
+
static int ds1307_get_time(struct device *dev, struct rtc_time *t)
{
struct ds1307 *ds1307 = dev_get_drvdata(dev);
@@ -334,7 +345,11 @@ static int __devinit ds1307_probe(struct i2c_client *client, const struct i2c_de
const struct chip_desc *chip;
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- chip = find_chip(client->name);
+ if (id)
+ chip = &chips[id->driver_data];
+ else
+ chip = find_chip(client->name);
+
if (!chip) {
dev_err(&client->dev, "unknown chip type '%s'\n",
client->name);
@@ -537,6 +552,7 @@ static struct i2c_driver ds1307_driver = {
},
.probe = ds1307_probe,
.remove = __devexit_p(ds1307_remove),
+ .id_table = ds1307_id,
};
static int __init ds1307_init(void)
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index dab6008..6dc05c4 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -41,6 +41,12 @@
#define DS1374_REG_SR_AF 0x01 /* Alarm Flag */
#define DS1374_REG_TCR 0x09 /* Trickle Charge */
+static struct i2c_device_id ds1374_id[] = {
+ OF_I2C_ID("dallas,ds1374", 0)
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, ds1374_id);
+
struct ds1374 {
struct i2c_client *client;
struct rtc_device *rtc;
@@ -429,6 +435,7 @@ static struct i2c_driver ds1374_driver = {
},
.probe = ds1374_probe,
.remove = __devexit_p(ds1374_remove),
+ .id_table = ds1374_id,
};
static int __init ds1374_init(void)
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 457f2ca..fc33f77 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -100,8 +100,21 @@ static const struct m41t80_chip_info m41t80_chip_info_tbl[] = {
},
};
+static struct i2c_device_id m41t80_id[] = {
+ OF_I2C_ID("stm,m41t80", 0)
+ OF_I2C_ID("stm,m41t81", M41T80_FEATURE_HT)
+ OF_I2C_ID("stm,m41t81s", M41T80_FEATURE_HT | M41T80_FEATURE_BL)
+ OF_I2C_ID("stm,m41t82", M41T80_FEATURE_HT | M41T80_FEATURE_BL)
+ OF_I2C_ID("stm,m41t83", M41T80_FEATURE_HT | M41T80_FEATURE_BL)
+ OF_I2C_ID("stm,m41t84", M41T80_FEATURE_HT | M41T80_FEATURE_BL)
+ OF_I2C_ID("stm,m41t85", M41T80_FEATURE_HT | M41T80_FEATURE_BL)
+ OF_I2C_ID("stm,m41t87", M41T80_FEATURE_HT | M41T80_FEATURE_BL)
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, m41t80_id);
+
struct m41t80_data {
- const struct m41t80_chip_info *chip;
+ u8 features;
struct rtc_device *rtc;
};
@@ -208,7 +221,7 @@ static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq)
struct m41t80_data *clientdata = i2c_get_clientdata(client);
u8 reg;
- if (clientdata->chip->features & M41T80_FEATURE_BL) {
+ if (clientdata->features & M41T80_FEATURE_BL) {
reg = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
seq_printf(seq, "battery\t\t: %s\n",
(reg & M41T80_FLAGS_BATT_LOW) ? "exhausted" : "ok");
@@ -761,7 +774,7 @@ static int m41t80_probe(struct i2c_client *client, const struct i2c_device_id *i
int i, rc = 0;
struct rtc_device *rtc = NULL;
struct rtc_time tm;
- const struct m41t80_chip_info *chip;
+ u8 features;
struct m41t80_data *clientdata = NULL;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C
@@ -773,17 +786,24 @@ static int m41t80_probe(struct i2c_client *client, const struct i2c_device_id *i
dev_info(&client->dev,
"chip found, driver version " DRV_VERSION "\n");
- chip = NULL;
- for (i = 0; i < ARRAY_SIZE(m41t80_chip_info_tbl); i++) {
- if (!strcmp(m41t80_chip_info_tbl[i].name, client->name)) {
- chip = &m41t80_chip_info_tbl[i];
- break;
+ if (id)
+ features = id->driver_data;
+ else {
+ const struct m41t80_chip_info *chip;
+
+ chip = NULL;
+ for (i = 0; i < ARRAY_SIZE(m41t80_chip_info_tbl); i++) {
+ if (!strcmp(m41t80_chip_info_tbl[i].name, client->name)) {
+ chip = &m41t80_chip_info_tbl[i];
+ break;
+ }
}
- }
- if (!chip) {
- dev_err(&client->dev, "%s is not supported\n", client->name);
- rc = -ENODEV;
- goto exit;
+ if (!chip) {
+ dev_err(&client->dev, "%s is not supported\n", client->name);
+ rc = -ENODEV;
+ goto exit;
+ }
+ features = chip->features;
}
clientdata = kzalloc(sizeof(*clientdata), GFP_KERNEL);
@@ -801,7 +821,7 @@ static int m41t80_probe(struct i2c_client *client, const struct i2c_device_id *i
}
clientdata->rtc = rtc;
- clientdata->chip = chip;
+ clientdata->features = features;
i2c_set_clientdata(client, clientdata);
/* Make sure HT (Halt Update) bit is cleared */
@@ -810,7 +830,7 @@ static int m41t80_probe(struct i2c_client *client, const struct i2c_device_id *i
goto ht_err;
if (rc & M41T80_ALHOUR_HT) {
- if (chip->features & M41T80_FEATURE_HT) {
+ if (features & M41T80_FEATURE_HT) {
m41t80_get_datetime(client, &tm);
dev_info(&client->dev, "HT bit was set!\n");
dev_info(&client->dev,
@@ -842,7 +862,7 @@ static int m41t80_probe(struct i2c_client *client, const struct i2c_device_id *i
goto exit;
#ifdef CONFIG_RTC_DRV_M41T80_WDT
- if (chip->features & M41T80_FEATURE_HT) {
+ if (features & M41T80_FEATURE_HT) {
rc = misc_register(&wdt_dev);
if (rc)
goto exit;
@@ -878,7 +898,7 @@ static int m41t80_remove(struct i2c_client *client)
struct rtc_device *rtc = clientdata->rtc;
#ifdef CONFIG_RTC_DRV_M41T80_WDT
- if (clientdata->chip->features & M41T80_FEATURE_HT) {
+ if (clientdata->features & M41T80_FEATURE_HT) {
misc_deregister(&wdt_dev);
unregister_reboot_notifier(&wdt_notifier);
}
@@ -896,6 +916,7 @@ static struct i2c_driver m41t80_driver = {
},
.probe = m41t80_probe,
.remove = m41t80_remove,
+ .id_table = m41t80_id,
};
static int __init m41t80_rtc_init(void)
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 25de13b..e2022c0 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -69,6 +69,15 @@ enum rtc_type {
rtc_rv5c387a,
};
+static struct i2c_device_id rs5c372_id[] = {
+ OF_I2C_ID("ricoh,rs5c372a", rtc_rs5c372a)
+ OF_I2C_ID("ricoh,rs5c372b", rtc_rs5c372b)
+ OF_I2C_ID("ricoh,rv5c386", rtc_rv5c386)
+ OF_I2C_ID("ricoh,rv5c387a", rtc_rv5c387a)
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, rs5c372_id);
+
/* REVISIT: this assumes that:
* - we're in the 21st century, so it's safe to ignore the century
* bit for rv5c38[67] (REG_MONTH bit 7);
@@ -522,7 +531,9 @@ static int rs5c372_probe(struct i2c_client *client, const struct i2c_device_id *
if (err < 0)
goto exit_kfree;
- if (strcmp(client->name, "rs5c372a") == 0)
+ if (id)
+ rs5c372->type = id->driver_data;
+ else if (strcmp(client->name, "rs5c372a") == 0)
rs5c372->type = rtc_rs5c372a;
else if (strcmp(client->name, "rs5c372b") == 0)
rs5c372->type = rtc_rs5c372b;
@@ -651,6 +662,7 @@ static struct i2c_driver rs5c372_driver = {
},
.probe = rs5c372_probe,
.remove = rs5c372_remove,
+ .id_table = rs5c372_id,
};
static __init int rs5c372_init(void)
^ permalink raw reply related
* [PATCH 19 3/5] Clean up error returns
From: Jon Smirl @ 2008-01-12 2:47 UTC (permalink / raw)
To: i2c, linuxppc-dev, linux-kernel
In-Reply-To: <20080112024737.7023.61680.stgit@terra.home>
Return errors that were being ignored in the mpc-i2c driver
Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
---
drivers/i2c/busses/i2c-mpc.c | 30 +++++++++++++++++-------------
1 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index d8de4ac..7c35a8f 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -180,7 +180,7 @@ static void mpc_i2c_stop(struct mpc_i2c *i2c)
static int mpc_write(struct mpc_i2c *i2c, int target,
const u8 * data, int length, int restart)
{
- int i;
+ int i, result;
unsigned timeout = i2c->adap.timeout;
u32 flags = restart ? CCR_RSTA : 0;
@@ -192,15 +192,17 @@ static int mpc_write(struct mpc_i2c *i2c, int target,
/* Write target byte */
writeb((target << 1), i2c->base + MPC_I2C_DR);
- if (i2c_wait(i2c, timeout, 1) < 0)
- return -1;
+ result = i2c_wait(i2c, timeout, 1);
+ if (result < 0)
+ return result;
for (i = 0; i < length; i++) {
/* Write data byte */
writeb(data[i], i2c->base + MPC_I2C_DR);
- if (i2c_wait(i2c, timeout, 1) < 0)
- return -1;
+ result = i2c_wait(i2c, timeout, 1);
+ if (result < 0)
+ return result;
}
return 0;
@@ -210,7 +212,7 @@ static int mpc_read(struct mpc_i2c *i2c, int target,
u8 * data, int length, int restart)
{
unsigned timeout = i2c->adap.timeout;
- int i;
+ int i, result;
u32 flags = restart ? CCR_RSTA : 0;
/* Start with MEN */
@@ -221,8 +223,9 @@ static int mpc_read(struct mpc_i2c *i2c, int target,
/* Write target address byte - this time with the read flag set */
writeb((target << 1) | 1, i2c->base + MPC_I2C_DR);
- if (i2c_wait(i2c, timeout, 1) < 0)
- return -1;
+ result = i2c_wait(i2c, timeout, 1);
+ if (result < 0)
+ return result;
if (length) {
if (length == 1)
@@ -234,8 +237,9 @@ static int mpc_read(struct mpc_i2c *i2c, int target,
}
for (i = 0; i < length; i++) {
- if (i2c_wait(i2c, timeout, 0) < 0)
- return -1;
+ result = i2c_wait(i2c, timeout, 0);
+ if (result < 0)
+ return result;
/* Generate txack on next to last byte */
if (i == length - 2)
@@ -321,9 +325,9 @@ static int fsl_i2c_probe(struct platform_device *pdev)
pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data;
- if (!(i2c = kzalloc(sizeof(*i2c), GFP_KERNEL))) {
+ i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
+ if (!i2c)
return -ENOMEM;
- }
i2c->irq = platform_get_irq(pdev, 0);
if (i2c->irq < 0) {
@@ -381,7 +385,7 @@ static int fsl_i2c_remove(struct platform_device *pdev)
i2c_del_adapter(&i2c->adap);
platform_set_drvdata(pdev, NULL);
- if (i2c->irq != 0)
+ if (i2c->irq != NO_IRQ)
free_irq(i2c->irq, i2c);
iounmap(i2c->base);
^ permalink raw reply related
* [PATCH 19 4/5] Convert PowerPC MPC i2c to of_platform_driver from platform_driver
From: Jon Smirl @ 2008-01-12 2:47 UTC (permalink / raw)
To: i2c, linuxppc-dev, linux-kernel
In-Reply-To: <20080112024737.7023.61680.stgit@terra.home>
Convert MPC i2c driver from being a platform_driver to an open firmware version. Error returns were improved. Routine names were changed from fsl_ to mpc_ to make them match the file name.
Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
---
arch/powerpc/sysdev/fsl_soc.c | 96 ----------------------
drivers/i2c/busses/i2c-mpc.c | 183 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 180 insertions(+), 99 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 94e5c73..d6ef264 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -318,102 +318,6 @@ err:
arch_initcall(gfar_of_init);
-#ifdef CONFIG_I2C_BOARDINFO
-#include <linux/i2c.h>
-
-static void __init of_register_i2c_devices(struct device_node *adap_node,
- int bus_num)
-{
- struct device_node *node = NULL;
- const char *compatible;
-
- while ((node = of_get_next_child(adap_node, node))) {
- struct i2c_board_info info = {};
- const u32 *addr;
- int len;
-
- addr = of_get_property(node, "reg", &len);
- if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
- printk(KERN_WARNING "fsl_soc.c: invalid i2c device entry\n");
- continue;
- }
-
- info.irq = irq_of_parse_and_map(node, 0);
- if (info.irq == NO_IRQ)
- info.irq = -1;
-
- compatible = of_get_property(node, "compatible", &len);
- if (!compatible) {
- printk(KERN_WARNING "i2c-mpc.c: invalid entry, missing compatible attribute\n");
- continue;
- }
- strncpy(info.type, compatible, sizeof(info.type));
-
- info.addr = *addr;
-
- i2c_register_board_info(bus_num, &info, 1);
- }
-}
-
-static int __init fsl_i2c_of_init(void)
-{
- struct device_node *np;
- unsigned int i;
- struct platform_device *i2c_dev;
- int ret;
-
- for (np = NULL, i = 0;
- (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL;
- i++) {
- struct resource r[2];
- struct fsl_i2c_platform_data i2c_data;
- const unsigned char *flags = NULL;
-
- memset(&r, 0, sizeof(r));
- memset(&i2c_data, 0, sizeof(i2c_data));
-
- ret = of_address_to_resource(np, 0, &r[0]);
- if (ret)
- goto err;
-
- of_irq_to_resource(np, 0, &r[1]);
-
- i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2);
- if (IS_ERR(i2c_dev)) {
- ret = PTR_ERR(i2c_dev);
- goto err;
- }
-
- i2c_data.device_flags = 0;
- flags = of_get_property(np, "dfsrr", NULL);
- if (flags)
- i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
-
- flags = of_get_property(np, "fsl5200-clocking", NULL);
- if (flags)
- i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200;
-
- ret =
- platform_device_add_data(i2c_dev, &i2c_data,
- sizeof(struct
- fsl_i2c_platform_data));
- if (ret)
- goto unreg;
-
- of_register_i2c_devices(np, i);
- }
-
- return 0;
-
-unreg:
- platform_device_unregister(i2c_dev);
-err:
- return ret;
-}
-
-arch_initcall(fsl_i2c_of_init);
-#endif
-
#ifdef CONFIG_PPC_83xx
static int __init mpc83xx_wdt_init(void)
{
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 7c35a8f..91fa73c 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -17,7 +17,7 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init.h>
-#include <linux/platform_device.h>
+#include <linux/of_platform.h>
#include <asm/io.h>
#include <linux/fsl_devices.h>
@@ -25,13 +25,13 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
-#define MPC_I2C_ADDR 0x00
+#define DRV_NAME "mpc-i2c"
+
#define MPC_I2C_FDR 0x04
#define MPC_I2C_CR 0x08
#define MPC_I2C_SR 0x0c
#define MPC_I2C_DR 0x10
#define MPC_I2C_DFSRR 0x14
-#define MPC_I2C_REGION 0x20
#define CCR_MEN 0x80
#define CCR_MIEN 0x40
@@ -316,6 +316,181 @@ static struct i2c_adapter mpc_ops = {
.retries = 1
};
+struct i2c_driver_device {
+ char *of_device;
+ char *i2c_driver;
+ char *i2c_type;
+};
+
+#ifdef CONFIG_PPC_MERGE
+
+static void of_register_i2c_devices(struct i2c_adapter *adap, struct device_node *adap_node)
+{
+ struct device_node *node = NULL;
+
+ while ((node = of_get_next_child(adap_node, node))) {
+ struct i2c_board_info info;
+ const u32 *addr;
+ const char *compatible;
+ int len;
+
+ addr = of_get_property(node, "reg", &len);
+ if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
+ printk(KERN_ERR "i2c-mpc.c: invalid entry, missing reg attribute\n");
+ continue;
+ }
+
+ info.irq = irq_of_parse_and_map(node, 0);
+ if (info.irq == NO_IRQ)
+ info.irq = -1;
+
+ compatible = of_get_property(node, "compatible", &len);
+ if (!compatible) {
+ printk(KERN_ERR "i2c-mpc.c: invalid entry, missing compatible attribute\n");
+ continue;
+ }
+
+ /* need full alias i2c:NOF,vendor,device */
+ strcpy(info.type, I2C_OF_MODULE_PREFIX);
+ strncat(info.type, compatible, sizeof(info.type));
+ request_module(info.type);
+
+ /* need module alias OF,vendor,device */
+ strcpy(info.type, OF_I2C_PREFIX);
+ strncat(info.type, compatible, sizeof(info.type));
+
+ info.driver_name[0] = '\0';
+ info.platform_data = NULL;
+ info.addr = *addr;
+
+ if (!i2c_new_device(adap, &info)) {
+ printk(KERN_ERR "i2c-mpc.c: Failed to load driver for %s\n", info.type);
+ continue;
+ }
+ }
+}
+
+static int mpc_i2c_probe(struct of_device *op, const struct of_device_id *match)
+{
+ int result = 0;
+ struct mpc_i2c *i2c;
+
+ i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
+ if (!i2c)
+ return -ENOMEM;
+
+ if (of_get_property(op->node, "dfsrr", NULL))
+ i2c->flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
+
+ if (of_device_is_compatible(op->node, "mpc5200-i2c"))
+ i2c->flags |= FSL_I2C_DEV_CLOCK_5200;
+
+ init_waitqueue_head(&i2c->queue);
+
+ i2c->base = of_iomap(op->node, 0);
+ if (!i2c->base) {
+ printk(KERN_ERR "i2c-mpc - failed to map controller\n");
+ result = -ENOMEM;
+ goto fail_map;
+ }
+
+ i2c->irq = irq_of_parse_and_map(op->node, 0);
+ if (i2c->irq == NO_IRQ) {
+ result = -ENXIO;
+ goto fail_irq;
+ }
+
+ result = request_irq(i2c->irq, mpc_i2c_isr, IRQF_SHARED, "i2c-mpc", i2c);
+ if (result < 0) {
+ printk(KERN_ERR "i2c-mpc - failed to attach interrupt\n");
+ goto fail_request;
+ }
+
+ mpc_i2c_setclock(i2c);
+
+ dev_set_drvdata(&op->dev, i2c);
+
+ i2c->adap = mpc_ops;
+ i2c_set_adapdata(&i2c->adap, i2c);
+ i2c->adap.dev.parent = &op->dev;
+
+ result = i2c_add_adapter(&i2c->adap);
+ if (result < 0) {
+ printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
+ goto fail_add;
+ }
+
+ of_register_i2c_devices(&i2c->adap, op->node);
+
+ return result;
+
+fail_add:
+ free_irq(i2c->irq, i2c);
+fail_request:
+ irq_dispose_mapping(i2c->irq);
+fail_irq:
+ iounmap(i2c->base);
+fail_map:
+ kfree(i2c);
+ return result;
+};
+
+static int mpc_i2c_remove(struct of_device *op)
+{
+ struct mpc_i2c *i2c = dev_get_drvdata(&op->dev);
+
+ i2c_del_adapter(&i2c->adap);
+ dev_set_drvdata(&op->dev, NULL);
+
+ if (i2c->irq != NO_IRQ)
+ free_irq(i2c->irq, i2c);
+
+ irq_dispose_mapping(i2c->irq);
+ iounmap(i2c->base);
+ kfree(i2c);
+ return 0;
+};
+
+static struct of_device_id mpc_i2c_of_match[] = {
+ {
+ .compatible = "fsl-i2c",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mpc_i2c_of_match);
+
+
+/* Structure for a device driver */
+static struct of_platform_driver mpc_i2c_driver = {
+ .match_table = mpc_i2c_of_match,
+ .probe = mpc_i2c_probe,
+ .remove = __devexit_p(mpc_i2c_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRV_NAME,
+ },
+};
+
+static int __init mpc_i2c_init(void)
+{
+ int rv;
+
+ rv = of_register_platform_driver(&mpc_i2c_driver);
+ if (rv)
+ printk(KERN_ERR DRV_NAME " of_register_platform_driver failed (%i)\n", rv);
+ return rv;
+}
+
+static void __exit mpc_i2c_exit(void)
+{
+ of_unregister_platform_driver(&mpc_i2c_driver);
+}
+
+module_init(mpc_i2c_init);
+module_exit(mpc_i2c_exit);
+
+#else
+
static int fsl_i2c_probe(struct platform_device *pdev)
{
int result = 0;
@@ -416,6 +591,8 @@ static void __exit fsl_i2c_exit(void)
module_init(fsl_i2c_init);
module_exit(fsl_i2c_exit);
+#endif
+
MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
MODULE_DESCRIPTION
("I2C-Bus adapter for MPC107 bridge and MPC824x/85xx/52xx processors");
^ permalink raw reply related
* [PATCH 19 1/5] Implement module aliasing for i2c to translate from device tree names
From: Jon Smirl @ 2008-01-12 2:47 UTC (permalink / raw)
To: i2c, linuxppc-dev, linux-kernel
In-Reply-To: <20080112024737.7023.61680.stgit@terra.home>
This patch allows new style i2c chip drivers to have alias names using
the official kernel aliasing system and MODULE_DEVICE_TABLE(). I've
tested it on PowerPC and x86. This change is required for PowerPC
device tree support.
Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
---
drivers/hwmon/f75375s.c | 4 ++--
drivers/i2c/chips/ds1682.c | 2 +-
drivers/i2c/chips/menelaus.c | 2 +-
drivers/i2c/chips/tps65010.c | 2 +-
drivers/i2c/chips/tsl2550.c | 2 +-
drivers/i2c/i2c-core.c | 24 +++++++++++++++++++++++-
drivers/rtc/rtc-ds1307.c | 2 +-
drivers/rtc/rtc-ds1374.c | 2 +-
drivers/rtc/rtc-m41t80.c | 2 +-
drivers/rtc/rtc-rs5c372.c | 2 +-
include/linux/i2c.h | 5 ++---
include/linux/mod_devicetable.h | 19 +++++++++++++++++++
scripts/mod/file2alias.c | 14 ++++++++++++++
13 files changed, 68 insertions(+), 14 deletions(-)
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 6892f76..2247de6 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -117,7 +117,7 @@ struct f75375_data {
static int f75375_attach_adapter(struct i2c_adapter *adapter);
static int f75375_detect(struct i2c_adapter *adapter, int address, int kind);
static int f75375_detach_client(struct i2c_client *client);
-static int f75375_probe(struct i2c_client *client);
+static int f75375_probe(struct i2c_client *client, const struct i2c_device_id *id);
static int f75375_remove(struct i2c_client *client);
static struct i2c_driver f75375_legacy_driver = {
@@ -628,7 +628,7 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data,
}
-static int f75375_probe(struct i2c_client *client)
+static int f75375_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct f75375_data *data = i2c_get_clientdata(client);
struct f75375s_platform_data *f75375s_pdata = client->dev.platform_data;
diff --git a/drivers/i2c/chips/ds1682.c b/drivers/i2c/chips/ds1682.c
index 9e94542..93c0441 100644
--- a/drivers/i2c/chips/ds1682.c
+++ b/drivers/i2c/chips/ds1682.c
@@ -200,7 +200,7 @@ static struct bin_attribute ds1682_eeprom_attr = {
/*
* Called when a ds1682 device is matched with this driver
*/
-static int ds1682_probe(struct i2c_client *client)
+static int ds1682_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int rc;
diff --git a/drivers/i2c/chips/menelaus.c b/drivers/i2c/chips/menelaus.c
index 2dea012..89ef9b6 100644
--- a/drivers/i2c/chips/menelaus.c
+++ b/drivers/i2c/chips/menelaus.c
@@ -1149,7 +1149,7 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
static struct i2c_driver menelaus_i2c_driver;
-static int menelaus_probe(struct i2c_client *client)
+static int menelaus_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct menelaus_chip *menelaus;
int rev = 0, val;
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
index e320994..6b13642 100644
--- a/drivers/i2c/chips/tps65010.c
+++ b/drivers/i2c/chips/tps65010.c
@@ -465,7 +465,7 @@ static int __exit tps65010_remove(struct i2c_client *client)
return 0;
}
-static int tps65010_probe(struct i2c_client *client)
+static int tps65010_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct tps65010 *tps;
int status;
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c
index 3de4b19..27c553d 100644
--- a/drivers/i2c/chips/tsl2550.c
+++ b/drivers/i2c/chips/tsl2550.c
@@ -364,7 +364,7 @@ static int tsl2550_init_client(struct i2c_client *client)
*/
static struct i2c_driver tsl2550_driver;
-static int __devinit tsl2550_probe(struct i2c_client *client)
+static int __devinit tsl2550_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct tsl2550_data *data;
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index b5e13e4..5f62230 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -47,6 +47,19 @@ static DEFINE_IDR(i2c_adapter_idr);
/* ------------------------------------------------------------------------- */
+static const struct i2c_device_id *i2c_match_id(
+ const struct i2c_device_id *id, struct i2c_client *client)
+{
+ /* only powerpc drivers implement the id_table,
+ * it is empty on other platforms */
+ while (id->name[0]) {
+ if (strcmp(client->name, id->name) == 0)
+ return id;
+ id++;
+ }
+ return NULL;
+}
+
static int i2c_device_match(struct device *dev, struct device_driver *drv)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -58,6 +71,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
if (!is_newstyle_driver(driver))
return 0;
+ /* match on an id table if there is one */
+ if (driver->id_table)
+ return i2c_match_id(driver->id_table, client) != NULL;
+
/* new style drivers use the same kind of driver matching policy
* as platform devices or SPI: compare device and driver IDs.
*/
@@ -89,12 +106,17 @@ static int i2c_device_probe(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_driver *driver = to_i2c_driver(dev->driver);
+ const struct i2c_device_id *id = NULL;
if (!driver->probe)
return -ENODEV;
client->driver = driver;
dev_dbg(dev, "probe\n");
- return driver->probe(client);
+
+ if (driver->id_table)
+ id = i2c_match_id(driver->id_table, client);
+
+ return driver->probe(client, id);
}
static int i2c_device_remove(struct device *dev)
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index bc1c7fe..9b0eab9 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -326,7 +326,7 @@ static struct bin_attribute nvram = {
static struct i2c_driver ds1307_driver;
-static int __devinit ds1307_probe(struct i2c_client *client)
+static int __devinit ds1307_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct ds1307 *ds1307;
int err = -ENODEV;
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 45bda18..dab6008 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -355,7 +355,7 @@ static const struct rtc_class_ops ds1374_rtc_ops = {
.ioctl = ds1374_ioctl,
};
-static int ds1374_probe(struct i2c_client *client)
+static int ds1374_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct ds1374 *ds1374;
int ret;
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 1cb33ca..457f2ca 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -756,7 +756,7 @@ static struct notifier_block wdt_notifier = {
*
*****************************************************************************
*/
-static int m41t80_probe(struct i2c_client *client)
+static int m41t80_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int i, rc = 0;
struct rtc_device *rtc = NULL;
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 6b67b50..25de13b 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -494,7 +494,7 @@ static void rs5c_sysfs_unregister(struct device *dev)
static struct i2c_driver rs5c372_driver;
-static int rs5c372_probe(struct i2c_client *client)
+static int rs5c372_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int err = 0;
struct rs5c372 *rs5c372;
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index a100c9f..0ca1a59 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -126,7 +126,7 @@ struct i2c_driver {
* With the driver model, device enumeration is NEVER done by drivers;
* it's done by infrastructure. (NEW STYLE DRIVERS ONLY)
*/
- int (*probe)(struct i2c_client *);
+ int (*probe)(struct i2c_client *, const struct i2c_device_id *id);
int (*remove)(struct i2c_client *);
/* driver model interfaces that don't relate to enumeration */
@@ -141,11 +141,10 @@ struct i2c_driver {
struct device_driver driver;
struct list_head list;
+ struct i2c_device_id *id_table;
};
#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
-#define I2C_NAME_SIZE 20
-
/**
* struct i2c_client - represent an I2C slave device
* @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index e9fddb4..f3aef9f 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -367,4 +367,23 @@ struct virtio_device_id {
};
#define VIRTIO_DEV_ANY_ID 0xffffffff
+/* i2c */
+
+/* These defines are used to separate PowerPC open firmware
+ * drivers into their own namespace */
+#define I2C_NAME_SIZE (16*3) /* Needs to be large enough to hold device tree style names */
+#define I2C_MODULE_PREFIX "i2c:"
+#ifdef CONFIG_OF
+#define OF_I2C_PREFIX "OF,"
+#define OF_I2C_ID(s,d) { OF_I2C_PREFIX s, (d) },
+#else
+#define OF_I2C_ID(s,d)
+#endif
+
+struct i2c_device_id {
+ char name[I2C_NAME_SIZE];
+ kernel_ulong_t driver_data; /* Data private to the driver */
+};
+
+
#endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index d802b5a..90a8d2c 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -539,6 +539,16 @@ static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
return 1;
}
+/* Looks like: i2c:s */
+static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
+ char *alias)
+{
+ char *tmp;
+ sprintf(alias, I2C_MODULE_PREFIX "%s", id->name);
+
+ return 1;
+}
+
/* Ignore any prefix, eg. v850 prepends _ */
static inline int sym_is(const char *symbol, const char *name)
{
@@ -669,6 +679,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
do_table(symval, sym->st_size,
sizeof(struct virtio_device_id), "virtio",
do_virtio_entry, mod);
+ else if (sym_is(symname, "__mod_i2c_device_table"))
+ do_table(symval, sym->st_size,
+ sizeof(struct i2c_device_id), "i2c",
+ do_i2c_entry, mod);
free(zeros);
}
^ permalink raw reply related
* [PATCH 19 0/5] Version 18, series to add device tree naming to i2c
From: Jon Smirl @ 2008-01-12 2:47 UTC (permalink / raw)
To: i2c, linuxppc-dev, linux-kernel
Updated to reflect comments in:
http://lkml.org/lkml/2008/1/11/272
Since copying i2c-mpc.c to maintain support for the ppc architecture seems to be an issue; instead rework i2c-mpc.c to use CONFIG_PPC_MERGE #ifdefs to support both the ppc and powerpc architecture. When ppc is deleted in six months these #ifdefs will need to be removed.
Another rework of the i2c for powerpc device tree patch. This version implements standard alias naming only on the powerpc platform and only for the device tree names. The old naming mechanism of i2c_client.name,driver_name is left in place and not changed for non-powerpc platforms. This patch is fully capable of dynamically loading the i2c modules. You can modprobe in the i2c-mpc driver and the i2c modules described in the device tree will be automatically loaded. Modules also work if compiled in.
The follow on patch to module-init-tools is also needed since the i2c subsystem has never implemented dynamic loading.
http://lkml.org/lkml/2007/12/17/493
The following series implements standard linux module aliasing for i2c modules on arch=powerpc. It then converts the mpc i2c driver from being a platform driver to an open firmware one. I2C device names are picked up from the device tree. Module aliasing is used to translate from device tree names into to linux kernel names. Several i2c drivers are updated to use the new aliasing.
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* [PATCH 19 5/5] Convert pfc8563 i2c driver from old style to new style
From: Jon Smirl @ 2008-01-12 2:47 UTC (permalink / raw)
To: i2c, linuxppc-dev, linux-kernel
In-Reply-To: <20080112024737.7023.61680.stgit@terra.home>
Convert pfc8563 i2c driver from old style to new style. The
driver is also modified to support device tree names via the
i2c mod alias mechanism.
Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
---
drivers/rtc/rtc-pcf8563.c | 107 +++++++++++----------------------------------
1 files changed, 27 insertions(+), 80 deletions(-)
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index 0242d80..e1ea2a0 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -25,10 +25,6 @@
* located at 0x51 will pass the validation routine due to
* the way the registers are implemented.
*/
-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Module parameters */
-I2C_CLIENT_INSMOD;
#define PCF8563_REG_ST1 0x00 /* status */
#define PCF8563_REG_ST2 0x01
@@ -72,9 +68,6 @@ struct pcf8563 {
int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */
};
-static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind);
-static int pcf8563_detach(struct i2c_client *client);
-
/*
* In the routines that deal directly with the pcf8563 hardware, we use
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
@@ -257,98 +250,52 @@ static const struct rtc_class_ops pcf8563_rtc_ops = {
.set_time = pcf8563_rtc_set_time,
};
-static int pcf8563_attach(struct i2c_adapter *adapter)
+static int pcf8563_remove(struct i2c_client *client)
{
- return i2c_probe(adapter, &addr_data, pcf8563_probe);
+ struct rtc_device *rtc = i2c_get_clientdata(client);
+
+ if (rtc)
+ rtc_device_unregister(rtc);
+
+ return 0;
}
+static struct i2c_device_id pcf8563_id[] = {
+ OF_I2C_ID("philips,pcf8563", 0)
+ OF_I2C_ID("epson,rtc8564", 0)
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, pcf8563_id);
+
+static int pcf8563_probe(struct i2c_client *client, const struct i2c_device_id *id);
+
static struct i2c_driver pcf8563_driver = {
.driver = {
- .name = "pcf8563",
+ .name = "rtc-pcf8563",
},
.id = I2C_DRIVERID_PCF8563,
- .attach_adapter = &pcf8563_attach,
- .detach_client = &pcf8563_detach,
+ .probe = &pcf8563_probe,
+ .remove = &pcf8563_remove,
+ .id_table = pcf8563_id,
};
-static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind)
+static int pcf8563_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
- struct pcf8563 *pcf8563;
- struct i2c_client *client;
+ int result;
struct rtc_device *rtc;
- int err = 0;
-
- dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
- err = -ENODEV;
- goto exit;
- }
-
- if (!(pcf8563 = kzalloc(sizeof(struct pcf8563), GFP_KERNEL))) {
- err = -ENOMEM;
- goto exit;
- }
-
- client = &pcf8563->client;
- client->addr = address;
- client->driver = &pcf8563_driver;
- client->adapter = adapter;
-
- strlcpy(client->name, pcf8563_driver.driver.name, I2C_NAME_SIZE);
-
- /* Verify the chip is really an PCF8563 */
- if (kind < 0) {
- if (pcf8563_validate_client(client) < 0) {
- err = -ENODEV;
- goto exit_kfree;
- }
- }
-
- /* Inform the i2c layer */
- if ((err = i2c_attach_client(client)))
- goto exit_kfree;
-
- dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
+ result = pcf8563_validate_client(client);
+ if (result)
+ return result;
rtc = rtc_device_register(pcf8563_driver.driver.name, &client->dev,
&pcf8563_rtc_ops, THIS_MODULE);
-
- if (IS_ERR(rtc)) {
- err = PTR_ERR(rtc);
- goto exit_detach;
- }
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
i2c_set_clientdata(client, rtc);
return 0;
-
-exit_detach:
- i2c_detach_client(client);
-
-exit_kfree:
- kfree(pcf8563);
-
-exit:
- return err;
-}
-
-static int pcf8563_detach(struct i2c_client *client)
-{
- struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
- int err;
- struct rtc_device *rtc = i2c_get_clientdata(client);
-
- if (rtc)
- rtc_device_unregister(rtc);
-
- if ((err = i2c_detach_client(client)))
- return err;
-
- kfree(pcf8563);
-
- return 0;
}
static int __init pcf8563_init(void)
^ permalink raw reply related
* Re: Device Tree & PCI
From: Scott Wood @ 2008-01-11 19:02 UTC (permalink / raw)
To: Rune Torgersen; +Cc: linuxppc-dev
In-Reply-To: <DCEAAC0833DD314AB0B58112AD99B93B03D9A381@ismail.innsys.innovsys.com>
On Fri, Jan 11, 2008 at 12:17:41PM -0600, Rune Torgersen wrote:
> PCI_INT: pic@5,10 {
> #interrupt-cells = <1>;
> interrupt-controller;
> reg = <5 10 4>; //
> Chip select, offset, length
> compatible = "apmax-pciintmux";
> interrupt-parent = <&PIC>;
> interrupts = <19 8>; //
> IRQ7, interrupt#25
> };
Is this interrupt controller getting registered before the PCI bus gets
probed?
-Scott
^ permalink raw reply
* Re: [PATCH 1/5] Warp Base Platform
From: Olof Johansson @ 2008-01-12 3:00 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: linuxppc-dev, Sean MacLennan
In-Reply-To: <20080112134005.a262c95c.sfr@canb.auug.org.au>
On Sat, Jan 12, 2008 at 01:40:05PM +1100, Stephen Rothwell wrote:
> Hi Sean,
>
> On Fri, 11 Jan 2008 18:39:15 -0500 Sean MacLennan <smaclennan@pikatech.com> wrote:
> >
> > +++ arch/powerpc/platforms/44x/warp-nand.c 2008-01-11 18:04:10.000000000 -0500
> > @@ -0,0 +1,85 @@
>
> You need a copyright/license notice.
Maybe your employer requires you to attach one with the files you create,
but it's not a requirement to get code accepted into the kernel. The
implied project-wide license is GPL.
-Olof
^ permalink raw reply
* Re: [PATCH 1/5] Warp Base Platform
From: Sean MacLennan @ 2008-01-12 2:52 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20080112134005.a262c95c.sfr@canb.auug.org.au>
Stephen Rothwell wrote:
> Hi Sean,
>
> On Fri, 11 Jan 2008 18:39:15 -0500 Sean MacLennan <smaclennan@pikatech.com> wrote:
>
>> +++ arch/powerpc/platforms/44x/warp-nand.c 2008-01-11 18:04:10.000000000 -0500
>> @@ -0,0 +1,85 @@
>>
>
> You need a copyright/license notice.
>
> The only other concern I have left is the extern in the C file, but that
> can be dealt with later.
>
>
Oops, meant to reply to everybody. Thanks for the copyright catch. Do I
need the GPL blurb, or is just a copyright ok? I notice Linux does not
seem to put the GPL blurb. For example sched.c.
And I also don't like the extern, but I don't see a good solution right now.
And while I have everybody's attention... The FPGA contains a simple
watchdog timer. Would it be ok to put that in the platform/44x/warp.c
file? It is a bit too specific to the taco to ever be accepted in the
drivers/watchdog. Or I could do a warp-watchdog.c .
Cheers,
Sean
^ permalink raw reply
* Re: [PATCH 1/5] Warp Base Platform
From: Sean MacLennan @ 2008-01-12 2:55 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20080112030015.GA9903@lixom.net>
Olof Johansson wrote:
> On Sat, Jan 12, 2008 at 01:40:05PM +1100, Stephen Rothwell wrote:
>
>> Hi Sean,
>>
>> On Fri, 11 Jan 2008 18:39:15 -0500 Sean MacLennan <smaclennan@pikatech.com> wrote:
>>
>>> +++ arch/powerpc/platforms/44x/warp-nand.c 2008-01-11 18:04:10.000000000 -0500
>>> @@ -0,0 +1,85 @@
>>>
>> You need a copyright/license notice.
>>
>
> Maybe your employer requires you to attach one with the files you create,
> but it's not a requirement to get code accepted into the kernel. The
> implied project-wide license is GPL.
>
>
> -Olof
>
I guess this implies I don't need the GPL blurb. I noticed that the
blurb I have used mentions GPL2 or later and I know Linus doesn't like GPL3.
^ permalink raw reply
* Re: [PATCH 1/5] Warp Base Platform
From: Sean MacLennan @ 2008-01-12 2:59 UTC (permalink / raw)
To: Olof Johansson; +Cc: Stephen Rothwell, linuxppc-dev
In-Reply-To: <20080112030015.GA9903@lixom.net>
Signed-off-by: Sean MacLennan <smaclennan@pikatech.com>
---
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 66a3d8c..b3e4c35 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -469,7 +469,7 @@ config MCA
config PCI
bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \
|| PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \
- || PPC_PS3
+ || PPC_PS3 || 44x
default y if !40x && !CPM2 && !8xx && !PPC_83xx \
&& !PPC_85xx && !PPC_86xx
default PCI_PERMEDIA if !4xx && !CPM2 && !8xx
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index d248013..a95409e 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -53,6 +53,19 @@ config RAINIER
help
This option enables support for the AMCC PPC440GRX evaluation board.
+config WARP
+ bool "PIKA Warp"
+ depends on 44x
+ default n
+ select 440EP
+ help
+ This option enables support for the PIKA Warp(tm) Appliance. The Warp
+ is a small computer replacement with up to 9 ports of FXO/FXS plus VOIP
+ stations and trunks.
+
+ See http://www.pikatechnologies.com/ and follow the "PIKA for Computer
+ Telephony Developers" link for more information.
+
#config LUAN
# bool "Luan"
# depends on 44x
@@ -75,6 +88,7 @@ config 440EP
select PPC_FPU
select IBM440EP_ERR42
select IBM_NEW_EMAC_ZMII
+ select USB_ARCH_HAS_OHCI
config 440EPX
bool
diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile
index a2a0dc1..7aaee9d 100644
--- a/arch/powerpc/platforms/44x/Makefile
+++ b/arch/powerpc/platforms/44x/Makefile
@@ -5,3 +5,5 @@ obj-$(CONFIG_BAMBOO) += bamboo.o
obj-$(CONFIG_SEQUOIA) += sequoia.o
obj-$(CONFIG_KATMAI) += katmai.o
obj-$(CONFIG_RAINIER) += rainier.o
+obj-$(CONFIG_WARP) += warp.o
+#obj-$(CONFIG_WARP) += warp-nand.o
--- /dev/null 2005-11-20 22:22:37.000000000 -0500
+++ arch/powerpc/platforms/44x/warp-nand.c 2008-01-11 21:56:02.000000000 -0500
@@ -0,0 +1,92 @@
+/*
+ * PIKA Warp(tm) NAND flash specific routines
+ *
+ * Copyright (c) 2008 PIKA Technologies
+ * Sean MacLennan <smaclennan@pikatech.com>
+ */
+
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/ndfc.h>
+
+
+#define CS_NAND_0 1 /* use chip select 1 for NAND device 0 */
+
+#define WARP_NAND_FLASH_REG_ADDR 0xD0000000UL
+#define WARP_NAND_FLASH_REG_SIZE 0x2000
+
+static struct resource warp_ndfc = {
+ .start = WARP_NAND_FLASH_REG_ADDR,
+ .end = WARP_NAND_FLASH_REG_ADDR + WARP_NAND_FLASH_REG_SIZE,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct mtd_partition nand_parts[] = {
+ {
+ .name = "nand",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+struct ndfc_controller_settings warp_ndfc_settings = {
+ .ccr_settings = (NDFC_CCR_BS(CS_NAND_0) | NDFC_CCR_ARAC1),
+ .ndfc_erpn = 0,
+};
+
+static struct ndfc_chip_settings warp_chip0_settings = {
+ .bank_settings = 0x80002222,
+};
+
+struct platform_nand_ctrl warp_nand_ctrl = {
+ .priv = &warp_ndfc_settings,
+};
+
+static struct platform_device warp_ndfc_device = {
+ .name = "ndfc-nand",
+ .id = 0,
+ .dev = {
+ .platform_data = &warp_nand_ctrl,
+ },
+ .num_resources = 1,
+ .resource = &warp_ndfc,
+};
+
+static struct nand_ecclayout nand_oob_16 = {
+ .eccbytes = 3,
+ .eccpos = { 0, 1, 2, 3, 6, 7 },
+ .oobfree = { {.offset = 8, .length = 16} }
+};
+
+static struct platform_nand_chip warp_nand_chip0 = {
+ .nr_chips = 1,
+ .chip_offset = CS_NAND_0,
+ .nr_partitions = ARRAY_SIZE(nand_parts),
+ .partitions = nand_parts,
+ .chip_delay = 50,
+ .ecclayout = &nand_oob_16,
+ .priv = &warp_chip0_settings,
+};
+
+static struct platform_device warp_nand_device = {
+ .name = "ndfc-chip",
+ .id = 0,
+ .num_resources = 1,
+ .resource = &warp_ndfc,
+ .dev = {
+ .platform_data = &warp_nand_chip0,
+ .parent = &warp_ndfc_device.dev,
+ }
+};
+
+static int warp_setup_nand_flash(void)
+{
+ platform_device_register(&warp_ndfc_device);
+ platform_device_register(&warp_nand_device);
+
+ return 0;
+}
+device_initcall(warp_setup_nand_flash);
--- /dev/null 2005-11-20 22:22:37.000000000 -0500
+++ arch/powerpc/platforms/44x/warp.c 2008-01-11 20:20:17.000000000 -0500
@@ -0,0 +1,175 @@
+/*
+ * PIKA Warp(tm) board specific routines
+ *
+ * Copyright (c) 2008 PIKA Technologies
+ * Sean MacLennan <smaclennan@pikatech.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/init.h>
+#include <linux/of_platform.h>
+#include <linux/kthread.h>
+
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/time.h>
+#include <asm/uic.h>
+
+#include "44x.h"
+
+
+static __initdata struct of_device_id warp_of_bus[] = {
+ { .compatible = "ibm,plb4", },
+ { .compatible = "ibm,opb", },
+ { .compatible = "ibm,ebc", },
+ {},
+};
+
+static int __init warp_device_probe(void)
+{
+ of_platform_bus_probe(NULL, warp_of_bus, NULL);
+ return 0;
+}
+machine_device_initcall(warp, warp_device_probe);
+
+static int __init warp_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (!of_flat_dt_is_compatible(root, "pika,warp"))
+ return 0;
+
+ return 1;
+}
+
+define_machine(warp) {
+ .name = "Warp",
+ .probe = warp_probe,
+ .progress = udbg_progress,
+ .init_IRQ = uic_init_tree,
+ .get_irq = uic_get_irq,
+ .restart = ppc44x_reset_system,
+ .calibrate_decr = generic_calibrate_decr,
+};
+
+/* This is for the power LEDs 1 = on, 0 = off, -1 = leave alone */
+void warp_set_power_leds(int green, int red)
+{
+ static void __iomem *gpio_base = NULL;
+ unsigned leds;
+
+ if (gpio_base == NULL) {
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP");
+ if (np == NULL) {
+ printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
+ return;
+ }
+ gpio_base = of_iomap(np, 0);
+ if (gpio_base == NULL) {
+ printk(KERN_ERR __FILE__ ": Unable to map gpio");
+ return;
+ }
+ }
+
+ leds = readl(gpio_base + 0x100);
+
+ switch (green) {
+ case 0: leds &= ~0x80; break;
+ case 1: leds |= 0x80; break;
+ }
+ switch (red) {
+ case 0: leds &= ~0x40; break;
+ case 1: leds |= 0x40; break;
+ }
+
+ writel(leds, gpio_base + 0x100);
+}
+EXPORT_SYMBOL(warp_set_power_leds);
+
+
+#ifdef CONFIG_SENSORS_AD7414
+static int pika_dtm_thread(void __iomem *fpga)
+{
+ extern int ad7414_get_temp(int index);
+
+ while (!kthread_should_stop()) {
+ int temp = ad7414_get_temp(0);
+
+ out_be32(fpga, temp);
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+ }
+
+ return 0;
+}
+
+static int pika_dtm_start(void __iomem *fpga)
+{
+ struct task_struct *dtm_thread;
+
+ dtm_thread = kthread_run(pika_dtm_thread, fpga + 0x20, "pika-dtm");
+ if (IS_ERR(dtm_thread)) {
+ printk(KERN_ERR __FILE__ ": Unable to start PIKA DTM thread\n");
+ return PTR_ERR(dtm_thread);
+ }
+
+ return 0;
+}
+#else
+static int pika_dtm_start(void __iomem *fpga)
+{
+ printk(KERN_WARN "PIKA DTM disabled\n");
+ return 0;
+}
+#endif
+
+
+static int __devinit warp_fpga_init(void)
+{
+ struct device_node *np;
+ struct resource res;
+ void __iomem *fpga;
+ int irq;
+
+ np = of_find_compatible_node(NULL, NULL, "pika,fpga");
+ if (np == NULL) {
+ printk(KERN_ERR __FILE__ ": Unable to find fpga\n");
+ return -ENOENT;
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (irq == NO_IRQ) {
+ printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n");
+ return -EBUSY;
+ }
+
+ /* We do not call of_iomap here since it would map in the entire
+ * fpga space, which is over 8k.
+ */
+ if (of_address_to_resource(np, 0, &res)) {
+ printk(KERN_ERR __FILE__ ": Unable to get FPGA address\n");
+ return -ENOENT;
+ }
+ fpga = ioremap(res.start, 0x24);
+ if (fpga == NULL) {
+ printk(KERN_ERR __FILE__ ": Unable to map FPGA\n");
+ return -ENOENT;
+ }
+
+ if (pika_dtm_start(fpga)) {
+ iounmap(fpga);
+ return -ENOENT;
+ }
+
+ /* SAM TODO: Start the watchdog here */
+
+ return 0;
+}
+device_initcall(warp_fpga_init);
^ permalink raw reply related
* Re: [i2c] [PATCH 19 1/5] Implement module aliasing for i2c to translate from device tree names
From: Jon Smirl @ 2008-01-12 3:00 UTC (permalink / raw)
To: i2c, linuxppc-dev, linux-kernel
In-Reply-To: <20080112024739.7023.90634.stgit@terra.home>
Comment was wrong, I2C_OF_MODULE_PREFIX was needed. Add it back.
Implement module aliasing for i2c to translate from device tree names
This patch allows new style i2c chip drivers to have alias names using
the official kernel aliasing system and MODULE_DEVICE_TABLE(). I've
tested it on PowerPC and x86. This change is required for PowerPC
device tree support.
Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
---
drivers/hwmon/f75375s.c | 4 ++--
drivers/i2c/chips/ds1682.c | 2 +-
drivers/i2c/chips/menelaus.c | 2 +-
drivers/i2c/chips/tps65010.c | 2 +-
drivers/i2c/chips/tsl2550.c | 2 +-
drivers/i2c/i2c-core.c | 24 +++++++++++++++++++++++-
drivers/rtc/rtc-ds1307.c | 2 +-
drivers/rtc/rtc-ds1374.c | 2 +-
drivers/rtc/rtc-m41t80.c | 2 +-
drivers/rtc/rtc-rs5c372.c | 2 +-
include/linux/i2c.h | 5 ++---
include/linux/mod_devicetable.h | 20 ++++++++++++++++++++
scripts/mod/file2alias.c | 12 ++++++++++++
13 files changed, 67 insertions(+), 14 deletions(-)
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 6892f76..2247de6 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -117,7 +117,7 @@ struct f75375_data {
static int f75375_attach_adapter(struct i2c_adapter *adapter);
static int f75375_detect(struct i2c_adapter *adapter, int address, int kind);
static int f75375_detach_client(struct i2c_client *client);
-static int f75375_probe(struct i2c_client *client);
+static int f75375_probe(struct i2c_client *client, const struct
i2c_device_id *id);
static int f75375_remove(struct i2c_client *client);
static struct i2c_driver f75375_legacy_driver = {
@@ -628,7 +628,7 @@ static void f75375_init(struct i2c_client *client,
struct f75375_data *data,
}
-static int f75375_probe(struct i2c_client *client)
+static int f75375_probe(struct i2c_client *client, const struct
i2c_device_id *id)
{
struct f75375_data *data = i2c_get_clientdata(client);
struct f75375s_platform_data *f75375s_pdata = client->dev.platform_data;
diff --git a/drivers/i2c/chips/ds1682.c b/drivers/i2c/chips/ds1682.c
index 9e94542..93c0441 100644
--- a/drivers/i2c/chips/ds1682.c
+++ b/drivers/i2c/chips/ds1682.c
@@ -200,7 +200,7 @@ static struct bin_attribute ds1682_eeprom_attr = {
/*
* Called when a ds1682 device is matched with this driver
*/
-static int ds1682_probe(struct i2c_client *client)
+static int ds1682_probe(struct i2c_client *client, const struct
i2c_device_id *id)
{
int rc;
diff --git a/drivers/i2c/chips/menelaus.c b/drivers/i2c/chips/menelaus.c
index 2dea012..89ef9b6 100644
--- a/drivers/i2c/chips/menelaus.c
+++ b/drivers/i2c/chips/menelaus.c
@@ -1149,7 +1149,7 @@ static inline void menelaus_rtc_init(struct
menelaus_chip *m)
static struct i2c_driver menelaus_i2c_driver;
-static int menelaus_probe(struct i2c_client *client)
+static int menelaus_probe(struct i2c_client *client, const struct
i2c_device_id *id)
{
struct menelaus_chip *menelaus;
int rev = 0, val;
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
index e320994..6b13642 100644
--- a/drivers/i2c/chips/tps65010.c
+++ b/drivers/i2c/chips/tps65010.c
@@ -465,7 +465,7 @@ static int __exit tps65010_remove(struct i2c_client *client)
return 0;
}
-static int tps65010_probe(struct i2c_client *client)
+static int tps65010_probe(struct i2c_client *client, const struct
i2c_device_id *id)
{
struct tps65010 *tps;
int status;
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c
index 3de4b19..27c553d 100644
--- a/drivers/i2c/chips/tsl2550.c
+++ b/drivers/i2c/chips/tsl2550.c
@@ -364,7 +364,7 @@ static int tsl2550_init_client(struct i2c_client *client)
*/
static struct i2c_driver tsl2550_driver;
-static int __devinit tsl2550_probe(struct i2c_client *client)
+static int __devinit tsl2550_probe(struct i2c_client *client, const
struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct tsl2550_data *data;
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index b5e13e4..5f62230 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -47,6 +47,19 @@ static DEFINE_IDR(i2c_adapter_idr);
/* ------------------------------------------------------------------------- */
+static const struct i2c_device_id *i2c_match_id(
+ const struct i2c_device_id *id, struct i2c_client *client)
+{
+ /* only powerpc drivers implement the id_table,
+ * it is empty on other platforms */
+ while (id->name[0]) {
+ if (strcmp(client->name, id->name) == 0)
+ return id;
+ id++;
+ }
+ return NULL;
+}
+
static int i2c_device_match(struct device *dev, struct device_driver *drv)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -58,6 +71,10 @@ static int i2c_device_match(struct device *dev,
struct device_driver *drv)
if (!is_newstyle_driver(driver))
return 0;
+ /* match on an id table if there is one */
+ if (driver->id_table)
+ return i2c_match_id(driver->id_table, client) != NULL;
+
/* new style drivers use the same kind of driver matching policy
* as platform devices or SPI: compare device and driver IDs.
*/
@@ -89,12 +106,17 @@ static int i2c_device_probe(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_driver *driver = to_i2c_driver(dev->driver);
+ const struct i2c_device_id *id = NULL;
if (!driver->probe)
return -ENODEV;
client->driver = driver;
dev_dbg(dev, "probe\n");
- return driver->probe(client);
+
+ if (driver->id_table)
+ id = i2c_match_id(driver->id_table, client);
+
+ return driver->probe(client, id);
}
static int i2c_device_remove(struct device *dev)
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index bc1c7fe..9b0eab9 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -326,7 +326,7 @@ static struct bin_attribute nvram = {
static struct i2c_driver ds1307_driver;
-static int __devinit ds1307_probe(struct i2c_client *client)
+static int __devinit ds1307_probe(struct i2c_client *client, const
struct i2c_device_id *id)
{
struct ds1307 *ds1307;
int err = -ENODEV;
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 45bda18..dab6008 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -355,7 +355,7 @@ static const struct rtc_class_ops ds1374_rtc_ops = {
.ioctl = ds1374_ioctl,
};
-static int ds1374_probe(struct i2c_client *client)
+static int ds1374_probe(struct i2c_client *client, const struct
i2c_device_id *id)
{
struct ds1374 *ds1374;
int ret;
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 1cb33ca..457f2ca 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -756,7 +756,7 @@ static struct notifier_block wdt_notifier = {
*
*****************************************************************************
*/
-static int m41t80_probe(struct i2c_client *client)
+static int m41t80_probe(struct i2c_client *client, const struct
i2c_device_id *id)
{
int i, rc = 0;
struct rtc_device *rtc = NULL;
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 6b67b50..25de13b 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -494,7 +494,7 @@ static void rs5c_sysfs_unregister(struct device *dev)
static struct i2c_driver rs5c372_driver;
-static int rs5c372_probe(struct i2c_client *client)
+static int rs5c372_probe(struct i2c_client *client, const struct
i2c_device_id *id)
{
int err = 0;
struct rs5c372 *rs5c372;
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index a100c9f..0ca1a59 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -126,7 +126,7 @@ struct i2c_driver {
* With the driver model, device enumeration is NEVER done by drivers;
* it's done by infrastructure. (NEW STYLE DRIVERS ONLY)
*/
- int (*probe)(struct i2c_client *);
+ int (*probe)(struct i2c_client *, const struct i2c_device_id *id);
int (*remove)(struct i2c_client *);
/* driver model interfaces that don't relate to enumeration */
@@ -141,11 +141,10 @@ struct i2c_driver {
struct device_driver driver;
struct list_head list;
+ struct i2c_device_id *id_table;
};
#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
-#define I2C_NAME_SIZE 20
-
/**
* struct i2c_client - represent an I2C slave device
* @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index e9fddb4..612d416 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -367,4 +367,24 @@ struct virtio_device_id {
};
#define VIRTIO_DEV_ANY_ID 0xffffffff
+/* i2c */
+
+/* These defines are used to separate PowerPC open firmware
+ * drivers into their own namespace */
+#define I2C_NAME_SIZE (16*3) /* Needs to be large enough to hold
device tree style names */
+#define I2C_MODULE_PREFIX "i2c:"
+#ifdef CONFIG_OF
+#define OF_I2C_PREFIX "OF,"
+#define I2C_OF_MODULE_PREFIX I2C_MODULE_PREFIX OF_I2C_PREFIX
+#define OF_I2C_ID(s,d) { OF_I2C_PREFIX s, (d) },
+#else
+#define OF_I2C_ID(s,d)
+#endif
+
+struct i2c_device_id {
+ char name[I2C_NAME_SIZE];
+ kernel_ulong_t driver_data; /* Data private to the driver */
+};
+
+
#endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index d802b5a..ac05b04 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -539,6 +539,14 @@ static int do_virtio_entry(const char *filename,
struct virtio_device_id *id,
return 1;
}
+/* Looks like: i2c:s */
+static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
+ char *alias)
+{
+ sprintf(alias, I2C_MODULE_PREFIX "%s", id->name);
+ return 1;
+}
+
/* Ignore any prefix, eg. v850 prepends _ */
static inline int sym_is(const char *symbol, const char *name)
{
@@ -669,6 +677,10 @@ void handle_moddevtable(struct module *mod,
struct elf_info *info,
do_table(symval, sym->st_size,
sizeof(struct virtio_device_id), "virtio",
do_virtio_entry, mod);
+ else if (sym_is(symname, "__mod_i2c_device_table"))
+ do_table(symval, sym->st_size,
+ sizeof(struct i2c_device_id), "i2c",
+ do_i2c_entry, mod);
free(zeros);
}
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply related
* Re: [PATCH 1/5] Warp Base Platform
From: Olof Johansson @ 2008-01-12 3:47 UTC (permalink / raw)
To: Sean MacLennan; +Cc: linuxppc-dev
In-Reply-To: <47882C3A.5050100@pikatech.com>
On Fri, Jan 11, 2008 at 09:55:54PM -0500, Sean MacLennan wrote:
> I guess this implies I don't need the GPL blurb. I noticed that the
> blurb I have used mentions GPL2 or later and I know Linus doesn't like GPL3.
You don't need it but people tend to include it by habit.
The two versions are essentially up to personal discretion. Some people
include the (or later) text, others do not. There are good arguments
both for and against. If you're in doubt, ask your company lawyer.
-Olof
^ permalink raw reply
* Re: [i2c] [PATCH 19 1/5] Implement module aliasing for i2c to translate from device tree names
From: Stephen Rothwell @ 2008-01-12 3:47 UTC (permalink / raw)
To: Jon Smirl; +Cc: linuxppc-dev, i2c, linux-kernel
In-Reply-To: <9e4733910801111900w6ace7c3bxe7e5f781db07ae4b@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1465 bytes --]
Hi Jon,
On Fri, 11 Jan 2008 22:00:42 -0500 "Jon Smirl" <jonsmirl@gmail.com> wrote:
>
> +++ b/drivers/hwmon/f75375s.c
> @@ -117,7 +117,7 @@ struct f75375_data {
> static int f75375_attach_adapter(struct i2c_adapter *adapter);
> static int f75375_detect(struct i2c_adapter *adapter, int address, int kind);
> static int f75375_detach_client(struct i2c_client *client);
> -static int f75375_probe(struct i2c_client *client);
> +static int f75375_probe(struct i2c_client *client, const struct
> i2c_device_id *id);
Looks like your mail client has wrapped this. Also in various later
spots.
> +++ b/drivers/i2c/i2c-core.c
> @@ -47,6 +47,19 @@ static DEFINE_IDR(i2c_adapter_idr);
>
> /* ------------------------------------------------------------------------- */
>
> +static const struct i2c_device_id *i2c_match_id(
> + const struct i2c_device_id *id, struct i2c_client *client)
Any reason that the "client" argument is not const as well?
> +++ b/include/linux/i2c.h
> @@ -141,11 +141,10 @@ struct i2c_driver {
>
> struct device_driver driver;
> struct list_head list;
> + struct i2c_device_id *id_table;
Any reason that this is not const? Making it const would allow divers to
make their tables const.
These are just small things (apart from the wrapping) that can be fixed
up with followup patches.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH 19 4/5] Convert PowerPC MPC i2c to of_platform_driver from platform_driver
From: Stephen Rothwell @ 2008-01-12 4:07 UTC (permalink / raw)
To: Jon Smirl; +Cc: linuxppc-dev, i2c, linux-kernel
In-Reply-To: <20080112024745.7023.66422.stgit@terra.home>
[-- Attachment #1: Type: text/plain, Size: 2684 bytes --]
Hi Jon,
On Fri, 11 Jan 2008 21:47:46 -0500 Jon Smirl <jonsmirl@gmail.com> wrote:
>
> +++ b/drivers/i2c/busses/i2c-mpc.c
> +static void of_register_i2c_devices(struct i2c_adapter *adap, struct device_node *adap_node)
> +{
> + struct device_node *node = NULL;
> +
> + while ((node = of_get_next_child(adap_node, node))) {
We have for_each_child_of_node(adap_node, node) now for this (and it
means you don't need to initialize the "node" above).
> + struct i2c_board_info info;
> + const u32 *addr;
> + const char *compatible;
> + int len;
> +
> + addr = of_get_property(node, "reg", &len);
> + if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
> + printk(KERN_ERR "i2c-mpc.c: invalid entry, missing reg attribute\n");
> + continue;
> + }
> +
> + info.irq = irq_of_parse_and_map(node, 0);
> + if (info.irq == NO_IRQ)
> + info.irq = -1;
> +
> + compatible = of_get_property(node, "compatible", &len);
> + if (!compatible) {
> + printk(KERN_ERR "i2c-mpc.c: invalid entry, missing compatible attribute\n");
> + continue;
You may need to clean up from the irq_of_pase_and_map().
> + }
> +
> + /* need full alias i2c:NOF,vendor,device */
> + strcpy(info.type, I2C_OF_MODULE_PREFIX);
> + strncat(info.type, compatible, sizeof(info.type));
> + request_module(info.type);
> +
> + /* need module alias OF,vendor,device */
> + strcpy(info.type, OF_I2C_PREFIX);
> + strncat(info.type, compatible, sizeof(info.type));
> +
> + info.driver_name[0] = '\0';
> + info.platform_data = NULL;
> + info.addr = *addr;
> +
> + if (!i2c_new_device(adap, &info)) {
> + printk(KERN_ERR "i2c-mpc.c: Failed to load driver for %s\n", info.type);
> + continue;
And again.
> + }
> + }
> +}
> +
> +static int mpc_i2c_probe(struct of_device *op, const struct of_device_id *match)
> +{
> + dev_set_drvdata(&op->dev, i2c);
> +
> + i2c->adap = mpc_ops;
> + i2c_set_adapdata(&i2c->adap, i2c);
> + i2c->adap.dev.parent = &op->dev;
> +
> + result = i2c_add_adapter(&i2c->adap);
> + if (result < 0) {
> + printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
> + goto fail_add;
> + }
> +
> + of_register_i2c_devices(&i2c->adap, op->node);
> +
> + return result;
> +
> +fail_add:
dev_set_dvdata(&op->dev, NULL);
> + free_irq(i2c->irq, i2c);
> +fail_request:
> + irq_dispose_mapping(i2c->irq);
> +fail_irq:
> + iounmap(i2c->base);
> +fail_map:
> + kfree(i2c);
> + return result;
> +};
> +static struct of_device_id mpc_i2c_of_match[] = {
const, please.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* RE: Device Tree & PCI
From: Rune Torgersen @ 2008-01-12 5:08 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20080111190215.GA10857@loki.buserror.net>
[-- Attachment #1: Type: text/plain, Size: 900 bytes --]
>From: Scott Wood
>Sent: Fri 1/11/2008 1:02 PM
>To: Rune Torgersen
>Cc: linuxppc-dev@ozlabs.org
>Subject: Re: Device Tree & PCI
>
>On Fri, Jan 11, 2008 at 12:17:41PM -0600, Rune Torgersen wrote:
>> PCI_INT: pic@5,10 {
>> #interrupt-cells = <1>;
>> interrupt-controller;
>> reg = <5 10 4>; //
>> Chip select, offset, length
>> compatible = "apmax-pciintmux";
>> interrupt-parent = <&PIC>;
>> interrupts = <19 8>; //
>> IRQ7, interrupt#25
>> };
>
>Is this interrupt controller getting registered before the PCI bus gets
>probed?
Yes, and we got the disk controller on the primary side to work fully.
The kernel is still spitting those messages out, and we have determined it does so when scanning the secondary side of the bridge, so we're suspecting our bridge node in the device tree is not correct.
[-- Attachment #2: Type: text/html, Size: 2530 bytes --]
^ permalink raw reply
* Re: [PATCH 2/5] Warp Base Platform - dts
From: Stefan Roese @ 2008-01-12 6:13 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Sean MacLennan
In-Reply-To: <4787FB77.5070905@pikatech.com>
On Saturday 12 January 2008, Sean MacLennan wrote:
> +++ arch/powerpc/boot/dts/warp.dts 2008-01-11 15:58:03.000000000 -0500
> @@ -0,0 +1,234 @@
> +/*
> + * Device Tree Source for PIKA Warp
> + *
> + * Copyright (c) 2008 PIKA Technologies
> + * Sean MacLennan <smaclennan@pikatech.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without
> + * any warranty of any kind, whether express or implied.
> + */
> +
> +/ {
> + #address-cells = <2>;
> + #size-cells = <1>;
> + model = "pika,warp";
> + compatible = "pika,warp";
> + dcr-parent = <&/cpus/cpu@0>;
> +
> + aliases {
> + ethernet0 = &EMAC0;
> + serial0 = &UART0;
> + };
> +
> + cpus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + cpu@0 {
> + device_type = "cpu";
> + model = "PowerPC,440EP";
> + reg = <0>;
> + clock-frequency = <0>; /* Filled in by zImage */
> + timebase-frequency = <0>; /* Filled in by zImage */
> + i-cache-line-size = <20>;
> + d-cache-line-size = <20>;
> + i-cache-size = <8000>;
> + d-cache-size = <8000>;
> + dcr-controller;
> + dcr-access-method = "native";
> + };
> + };
> +
> + memory {
> + device_type = "memory";
> + reg = <0 0 0>; /* Filled in by zImage */
> + };
> +
> + UIC0: interrupt-controller0 {
> + compatible = "ibm,uic-440ep","ibm,uic";
> + interrupt-controller;
> + cell-index = <0>;
> + dcr-reg = <0c0 009>;
> + #address-cells = <0>;
> + #size-cells = <0>;
> + #interrupt-cells = <2>;
> + };
> +
> + UIC1: interrupt-controller1 {
> + compatible = "ibm,uic-440ep","ibm,uic";
> + interrupt-controller;
> + cell-index = <1>;
> + dcr-reg = <0d0 009>;
> + #address-cells = <0>;
> + #size-cells = <0>;
> + #interrupt-cells = <2>;
> + interrupts = <1e 4 1f 4>; /* cascade */
> + interrupt-parent = <&UIC0>;
> + };
> +
> + SDR0: sdr {
> + compatible = "ibm,sdr-440ep";
> + dcr-reg = <00e 002>;
> + };
> +
> + CPR0: cpr {
> + compatible = "ibm,cpr-440ep";
> + dcr-reg = <00c 002>;
> + };
> +
> + plb {
> + compatible = "ibm,plb-440ep", "ibm,plb-440gp", "ibm,plb4";
> + #address-cells = <2>;
> + #size-cells = <1>;
> + ranges;
> + clock-frequency = <0>; /* Filled in by zImage */
> +
> + SDRAM0: sdram {
> + compatible = "ibm,sdram-440ep", "ibm,sdram-405gp";
> + dcr-reg = <010 2>;
> + };
> +
> + DMA0: dma {
> + compatible = "ibm,dma-440ep", "ibm,dma-440gp";
> + dcr-reg = <100 027>;
> + };
> +
> + MAL0: mcmal {
> + compatible = "ibm,mcmal-440ep", "ibm,mcmal-440gp", "ibm,mcmal";
> + dcr-reg = <180 62>;
> + num-tx-chans = <4>;
> + num-rx-chans = <2>;
> + interrupt-parent = <&MAL0>;
> + interrupts = <0 1 2 3 4>;
> + #interrupt-cells = <1>;
> + #address-cells = <0>;
> + #size-cells = <0>;
> + interrupt-map = </*TXEOB*/ 0 &UIC0 a 4
> + /*RXEOB*/ 1 &UIC0 b 4
> + /*SERR*/ 2 &UIC1 0 4
> + /*TXDE*/ 3 &UIC1 1 4
> + /*RXDE*/ 4 &UIC1 2 4>;
> + };
> +
> + POB0: opb {
> + compatible = "ibm,opb-440ep", "ibm,opb-440gp", "ibm,opb";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + ranges = <00000000 0 00000000 80000000
> + 80000000 0 80000000 80000000>;
> + interrupt-parent = <&UIC1>;
> + interrupts = <7 4>;
> + clock-frequency = <0>; /* Filled in by zImage */
> +
> + EBC0: ebc {
> + compatible = "ibm,ebc-440ep", "ibm,ebc-440gp", "ibm,ebc";
> + dcr-reg = <012 2>;
> + #address-cells = <2>;
> + #size-cells = <1>;
> + clock-frequency = <0>; /* Filled in by zImage */
> + interrupts = <5 1>;
> + interrupt-parent = <&UIC1>;
> +
> + fpga@2,0 {
> + compatible = "pika,fpga";
> + reg = <2 0 2200>;
> + interrupts = <18 8>;
> + interrupt-parent = <&UIC0>;
> + };
> +
> + nor_flash@0,0 {
> + compatible = "amd,s29gl512n", "cfi-flash";
> + bank-width = <2>;
> + reg = <0 0 4000000>;
> + #address-cells = <1>;
> + #size-cells = <1>;
> + partition@0 {
> + label = "kernel";
> + reg = <0 180000>;
> + };
> + partition@180000 {
> + label = "root";
> + reg = <180000 3480000>;
> + };
> + partition@3600000 {
> + label = "user";
> + reg = <3600000 900000>;
> + };
> + partition@3f00000 {
> + label = "fpga";
> + reg = <3f00000 40000>;
> + };
> + partition@3f40000 {
> + label = "env";
> + reg = <3f40000 40000>;
> + };
> + partition@3f80000 {
> + label = "u-boot";
> + reg = <3f80000 80000>;
> + };
> + };
> + };
> +
> + UART0: serial@ef600300 {
> + device_type = "serial";
> + compatible = "ns16550";
> + reg = <ef600300 8>;
> + virtual-reg = <ef600300>;
> + clock-frequency = <0>; /* Filled in by zImage */
> + current-speed = <1c200>;
> + interrupt-parent = <&UIC0>;
> + interrupts = <0 4>;
> + };
> +
> + IIC0: i2c@ef600700 {
> + compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic";
> + reg = <ef600700 14>;
> + interrupt-parent = <&UIC0>;
> + interrupts = <2 4>;
> + };
> +
> + GPIO0: gpio@ef600b00 {
> + compatible = "ibm,gpio-440ep";
> + reg = <ef600b00 148>;
> + };
You define here one gpio node that covers both gpio controllers of the 440EP.
I suggest to use two nodes here, like:
GPIO0: gpio@ef600b00 {
compatible = "ibm,gpio-440ep";
reg = <ef600b00 48>;
};
GPIO1: gpio@ef600c00 {
compatible = "ibm,gpio-440ep";
reg = <ef600c00 48>;
};
Best regards,
Stefan
^ permalink raw reply
* Re: [PATCH 1/5] Warp Base Platform
From: Stefan Roese @ 2008-01-12 6:23 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Stephen Rothwell, Sean MacLennan
In-Reply-To: <4787FE23.7010201@pikatech.com>
On Saturday 12 January 2008, Sean MacLennan wrote:
> Josh Boyer wrote:
> >> + if (gpio_base == NULL) {
> >> + printk("ERROR: Unable to remap GPIO base.\n");
> >> + return;
> >> + }
> >> + }
> >> +
> >> + leds = readl(gpio_base + 0x100);
> >
> > Do you really want readl here? That will byte-swap.
>
> According to the docs I got from the hardware guys, this is correct.
> That does *not* mean they didn't get it wrong. Unfortunately, it was
> just on a piece of paper and I don't know if I still have it.
You are accessing the 440EP GPIO controller here right? Then you really should
use big endian access routines. From you code I assume that you have
connected the LED signals to GPIO00 and GPIO01. I suggest to use code that
looks like this:
#define LED_GREEN (0x80000000 >> 0)
#define LED_RED (0x80000000 >> 1)
leds = in_be32(gpio_base);
switch (green) {
case 0: leds &= ~LED_GREEN; break;
case 1: leds |= LED_GREEN; break;
}
switch (red) {
case 0: leds &= ~LED_RED; break;
case 1: leds |= LED_RED; break;
}
outbe32(leds, gpio_base);
And when you change the dts to describe both GPIO controllers you should map
the 2nd one and remove the 0x100 offset above as I have done above.
Best regards,
Stefan
^ permalink raw reply
* Re: [PATCH 1/5] Warp Base Platform
From: Sean MacLennan @ 2008-01-12 6:35 UTC (permalink / raw)
To: Stefan Roese; +Cc: linuxppc-dev, Stephen Rothwell
In-Reply-To: <200801120723.29393.sr@denx.de>
Stefan Roese wrote:
> On Saturday 12 January 2008, Sean MacLennan wrote:
>
>> Josh Boyer wrote:
>>
>>>> + if (gpio_base == NULL) {
>>>> + printk("ERROR: Unable to remap GPIO base.\n");
>>>> + return;
>>>> + }
>>>> + }
>>>> +
>>>> + leds = readl(gpio_base + 0x100);
>>>>
>>> Do you really want readl here? That will byte-swap.
>>>
>> According to the docs I got from the hardware guys, this is correct.
>> That does *not* mean they didn't get it wrong. Unfortunately, it was
>> just on a piece of paper and I don't know if I still have it.
>>
>
> You are accessing the 440EP GPIO controller here right? Then you really should
> use big endian access routines. From you code I assume that you have
> connected the LED signals to GPIO00 and GPIO01. I suggest to use code that
> looks like this:
>
> #define LED_GREEN (0x80000000 >> 0)
> #define LED_RED (0x80000000 >> 1)
>
> leds = in_be32(gpio_base);
>
> switch (green) {
> case 0: leds &= ~LED_GREEN; break;
> case 1: leds |= LED_GREEN; break;
> }
> switch (red) {
> case 0: leds &= ~LED_RED; break;
> case 1: leds |= LED_RED; break;
> }
>
> outbe32(leds, gpio_base);
>
> And when you change the dts to describe both GPIO controllers you should map
> the 2nd one and remove the 0x100 offset above as I have done above.
>
> Best regards,
> Stefan
>
Ok. I will look into that. What is the best practice for looking up the
second GPIO controller? I have been using of_find_compatible_type. I
could call it a second time with a from arg.
Cheers,
Sean
^ permalink raw reply
* Re: [PATCH] ibm_newemac: Increase number of default rx-/tx-buffers
From: Stefan Roese @ 2008-01-12 7:26 UTC (permalink / raw)
To: benh; +Cc: netdev, linuxppc-dev
In-Reply-To: <1200089457.6896.65.camel@pasglop>
On Friday 11 January 2008, Benjamin Herrenschmidt wrote:
> On Fri, 2008-01-11 at 09:48 -0800, Eugene Surovegin wrote:
> > On Sat, Jan 05, 2008 at 01:38:17PM +0100, Stefan Roese wrote:
> > > On Saturday 05 January 2008, Benjamin Herrenschmidt wrote:
> > > > On Sat, 2008-01-05 at 10:50 +0100, Stefan Roese wrote:
> > > > > Performance tests done by AMCC have shown that 256 buffer increase
> > > > > the performance of the Linux EMAC driver. So let's update the
> > > > > default values to match this setup.
> > > > >
> > > > > Signed-off-by: Stefan Roese <sr@denx.de>
> > > > > ---
> > > >
> > > > Do we have the numbers ? Did they also measure latency ?
> > >
> > > I hoped this question would not come. ;) No, unfortunately I don't have
> > > any numbers. Just the recommendation from AMCC to always use 256
> > > buffers.
> >
> > This cannot be true for all chips. Default numbers I selected weren't
> > random. In particular, 256 for Tx doesn't make a lot of sense for 405.
> > You just gonna waste memory.
This may be the case with the "old" 405 PPC's. But with the new ones coming
out right now, like the up to 666MHz 405EX with GBit support, 256 could be an
improvement. I still owe you figures though. Will try to do some testing in a
short while.
> > I'd be quite reluctant to follow such advices from AMCC without actual
> > details.
>
> I think we can make defaults based on other config options nowadays. Not
> very nice but we could do things like
>
> default 128 if PPC_40x
> default 256
>
> Or even more detailed.
We shouldn't make it too complicated. We can always select different settings
in the defconfig file. My thinking here is to better wast a little memory
with a potential performance improvement. Just me 0.02$
Best regards,
Stefan
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox