From 6e56dd3d0e1e899a824c247aa72bc4250ce7668a Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Wed, 17 Feb 2010 11:19:17 +0100 Subject: i2c-mpc: use __devinit[data] for initialization functions and data "__devinit[data]" has not yet been used for all initialization functions and data. To avoid truncating lines, the struct "mpc_i2c_match_data" has been renamed to "mpc_i2c_data", which is even the better name. Signed-off-by: Wolfgang Grandegger Tested-by: Wolfram Sang Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-mpc.c | 99 ++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 53 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index f627001108b..2f74d9b6c0b 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -66,7 +66,7 @@ struct mpc_i2c_divider { u16 fdr; /* including dfsrr */ }; -struct mpc_i2c_match_data { +struct mpc_i2c_data { void (*setclock)(struct device_node *node, struct mpc_i2c *i2c, u32 clock, u32 prescaler); @@ -165,7 +165,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) } #ifdef CONFIG_PPC_MPC52xx -static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = { +static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitconst = { {20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23}, {28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02}, {36, 0x26}, {40, 0x27}, {44, 0x04}, {48, 0x28}, @@ -186,7 +186,8 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = { {10240, 0x9d}, {12288, 0x9e}, {15360, 0x9f} }; -int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler) +static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, + int prescaler) { const struct mpc_i2c_divider *div = NULL; unsigned int pvr = mfspr(SPRN_PVR); @@ -215,9 +216,9 @@ int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler) return div ? (int)div->fdr : -EINVAL; } -static void mpc_i2c_setclock_52xx(struct device_node *node, - struct mpc_i2c *i2c, - u32 clock, u32 prescaler) +static void __devinit mpc_i2c_setclock_52xx(struct device_node *node, + struct mpc_i2c *i2c, + u32 clock, u32 prescaler) { int ret, fdr; @@ -230,15 +231,15 @@ static void mpc_i2c_setclock_52xx(struct device_node *node, dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr); } #else /* !CONFIG_PPC_MPC52xx */ -static void mpc_i2c_setclock_52xx(struct device_node *node, - struct mpc_i2c *i2c, - u32 clock, u32 prescaler) +static void __devinit mpc_i2c_setclock_52xx(struct device_node *node, + struct mpc_i2c *i2c, + u32 clock, u32 prescaler) { } #endif /* CONFIG_PPC_MPC52xx*/ #ifdef CONFIG_FSL_SOC -static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = { +static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] __devinitconst = { {160, 0x0120}, {192, 0x0121}, {224, 0x0122}, {256, 0x0123}, {288, 0x0100}, {320, 0x0101}, {352, 0x0601}, {384, 0x0102}, {416, 0x0602}, {448, 0x0126}, {480, 0x0103}, {512, 0x0127}, @@ -258,7 +259,7 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = { {49152, 0x011e}, {61440, 0x011f} }; -u32 mpc_i2c_get_sec_cfg_8xxx(void) +static u32 __devinit mpc_i2c_get_sec_cfg_8xxx(void) { struct device_node *node = NULL; u32 __iomem *reg; @@ -287,7 +288,8 @@ u32 mpc_i2c_get_sec_cfg_8xxx(void) return val; } -int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, u32 prescaler) +static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, + u32 prescaler) { const struct mpc_i2c_divider *div = NULL; u32 divider; @@ -320,9 +322,9 @@ int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, u32 prescaler) return div ? (int)div->fdr : -EINVAL; } -static void mpc_i2c_setclock_8xxx(struct device_node *node, - struct mpc_i2c *i2c, - u32 clock, u32 prescaler) +static void __devinit mpc_i2c_setclock_8xxx(struct device_node *node, + struct mpc_i2c *i2c, + u32 clock, u32 prescaler) { int ret, fdr; @@ -338,9 +340,9 @@ static void mpc_i2c_setclock_8xxx(struct device_node *node, } #else /* !CONFIG_FSL_SOC */ -static void mpc_i2c_setclock_8xxx(struct device_node *node, - struct mpc_i2c *i2c, - u32 clock, u32 prescaler) +static void __devinit mpc_i2c_setclock_8xxx(struct device_node *node, + struct mpc_i2c *i2c, + u32 clock, u32 prescaler) { } #endif /* CONFIG_FSL_SOC */ @@ -529,8 +531,8 @@ static int __devinit fsl_i2c_probe(struct of_device *op, clock = *prop; if (match->data) { - struct mpc_i2c_match_data *data = - (struct mpc_i2c_match_data *)match->data; + struct mpc_i2c_data *data = + (struct mpc_i2c_data *)match->data; data->setclock(op->node, i2c, clock, data->prescaler); } else { /* Backwards compatibility */ @@ -582,44 +584,35 @@ static int __devexit fsl_i2c_remove(struct of_device *op) return 0; }; +static struct mpc_i2c_data mpc_i2c_data_52xx __devinitdata = { + .setclock = mpc_i2c_setclock_52xx, +}; + +static struct mpc_i2c_data mpc_i2c_data_8313 __devinitdata = { + .setclock = mpc_i2c_setclock_8xxx, +}; + +static struct mpc_i2c_data mpc_i2c_data_8543 __devinitdata = { + .setclock = mpc_i2c_setclock_8xxx, + .prescaler = 2, +}; + +static struct mpc_i2c_data mpc_i2c_data_8544 __devinitdata = { + .setclock = mpc_i2c_setclock_8xxx, + .prescaler = 3, +}; + static const struct of_device_id mpc_i2c_of_match[] = { - {.compatible = "mpc5200-i2c", - .data = &(struct mpc_i2c_match_data) { - .setclock = mpc_i2c_setclock_52xx, - }, - }, - {.compatible = "fsl,mpc5200b-i2c", - .data = &(struct mpc_i2c_match_data) { - .setclock = mpc_i2c_setclock_52xx, - }, - }, - {.compatible = "fsl,mpc5200-i2c", - .data = &(struct mpc_i2c_match_data) { - .setclock = mpc_i2c_setclock_52xx, - }, - }, - {.compatible = "fsl,mpc8313-i2c", - .data = &(struct mpc_i2c_match_data) { - .setclock = mpc_i2c_setclock_8xxx, - }, - }, - {.compatible = "fsl,mpc8543-i2c", - .data = &(struct mpc_i2c_match_data) { - .setclock = mpc_i2c_setclock_8xxx, - .prescaler = 2, - }, - }, - {.compatible = "fsl,mpc8544-i2c", - .data = &(struct mpc_i2c_match_data) { - .setclock = mpc_i2c_setclock_8xxx, - .prescaler = 3, - }, + {.compatible = "mpc5200-i2c", .data = &mpc_i2c_data_52xx, }, + {.compatible = "fsl,mpc5200b-i2c", .data = &mpc_i2c_data_52xx, }, + {.compatible = "fsl,mpc5200-i2c", .data = &mpc_i2c_data_52xx, }, + {.compatible = "fsl,mpc8313-i2c", .data = &mpc_i2c_data_8313, }, + {.compatible = "fsl,mpc8543-i2c", .data = &mpc_i2c_data_8543, }, + {.compatible = "fsl,mpc8544-i2c", .data = &mpc_i2c_data_8544, }, /* Backward compatibility */ - }, {.compatible = "fsl-i2c", }, {}, }; - MODULE_DEVICE_TABLE(of, mpc_i2c_of_match); -- cgit v1.2.3 From a93522116ee5aa13eeb74c0fd73d8c5d15211e64 Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Wed, 17 Feb 2010 11:19:18 +0100 Subject: i2c-mpc: rename "setclock" initialization functions to "setup" To prepare support for the MPC512x processors from Freescale the "setclock" initialization functions have been renamed to "setup" because I2C interrupts must be enabled for the MPC512x by this function as well. Signed-off-by: Wolfgang Grandegger Acked-by: Wolfram Sang Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-mpc.c | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 2f74d9b6c0b..370c342e5e8 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -67,9 +67,8 @@ struct mpc_i2c_divider { }; struct mpc_i2c_data { - void (*setclock)(struct device_node *node, - struct mpc_i2c *i2c, - u32 clock, u32 prescaler); + void (*setup)(struct device_node *node, struct mpc_i2c *i2c, + u32 clock, u32 prescaler); u32 prescaler; }; @@ -216,9 +215,9 @@ static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, return div ? (int)div->fdr : -EINVAL; } -static void __devinit mpc_i2c_setclock_52xx(struct device_node *node, - struct mpc_i2c *i2c, - u32 clock, u32 prescaler) +static void __devinit mpc_i2c_setup_52xx(struct device_node *node, + struct mpc_i2c *i2c, + u32 clock, u32 prescaler) { int ret, fdr; @@ -231,9 +230,9 @@ static void __devinit mpc_i2c_setclock_52xx(struct device_node *node, dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr); } #else /* !CONFIG_PPC_MPC52xx */ -static void __devinit mpc_i2c_setclock_52xx(struct device_node *node, - struct mpc_i2c *i2c, - u32 clock, u32 prescaler) +static void __devinit mpc_i2c_setup_52xx(struct device_node *node, + struct mpc_i2c *i2c, + u32 clock, u32 prescaler) { } #endif /* CONFIG_PPC_MPC52xx*/ @@ -322,9 +321,9 @@ static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, return div ? (int)div->fdr : -EINVAL; } -static void __devinit mpc_i2c_setclock_8xxx(struct device_node *node, - struct mpc_i2c *i2c, - u32 clock, u32 prescaler) +static void __devinit mpc_i2c_setup_8xxx(struct device_node *node, + struct mpc_i2c *i2c, + u32 clock, u32 prescaler) { int ret, fdr; @@ -340,9 +339,9 @@ static void __devinit mpc_i2c_setclock_8xxx(struct device_node *node, } #else /* !CONFIG_FSL_SOC */ -static void __devinit mpc_i2c_setclock_8xxx(struct device_node *node, - struct mpc_i2c *i2c, - u32 clock, u32 prescaler) +static void __devinit mpc_i2c_setup_8xxx(struct device_node *node, + struct mpc_i2c *i2c, + u32 clock, u32 prescaler) { } #endif /* CONFIG_FSL_SOC */ @@ -533,12 +532,11 @@ static int __devinit fsl_i2c_probe(struct of_device *op, if (match->data) { struct mpc_i2c_data *data = (struct mpc_i2c_data *)match->data; - data->setclock(op->node, i2c, clock, data->prescaler); + data->setup(op->node, i2c, clock, data->prescaler); } else { /* Backwards compatibility */ if (of_get_property(op->node, "dfsrr", NULL)) - mpc_i2c_setclock_8xxx(op->node, i2c, - clock, 0); + mpc_i2c_setup_8xxx(op->node, i2c, clock, 0); } } @@ -585,20 +583,20 @@ static int __devexit fsl_i2c_remove(struct of_device *op) }; static struct mpc_i2c_data mpc_i2c_data_52xx __devinitdata = { - .setclock = mpc_i2c_setclock_52xx, + .setup = mpc_i2c_setup_52xx, }; static struct mpc_i2c_data mpc_i2c_data_8313 __devinitdata = { - .setclock = mpc_i2c_setclock_8xxx, + .setup = mpc_i2c_setup_8xxx, }; static struct mpc_i2c_data mpc_i2c_data_8543 __devinitdata = { - .setclock = mpc_i2c_setclock_8xxx, + .setup = mpc_i2c_setup_8xxx, .prescaler = 2, }; static struct mpc_i2c_data mpc_i2c_data_8544 __devinitdata = { - .setclock = mpc_i2c_setclock_8xxx, + .setup = mpc_i2c_setup_8xxx, .prescaler = 3, }; -- cgit v1.2.3 From f00d738f04899534e2c372b2ad8b670050a945e2 Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Wed, 17 Feb 2010 11:19:19 +0100 Subject: i2c-mpc: add support for the MPC512x processors from Freescale As I2C interrupts must be enabled for the MPC512x by the setup function as well, "fsl,preserve-clocking" is handled in a slighly different way. Also, the old settings are now reported calling dev_dbg(). For the MPC512x the clock setup function of the MPC52xx can be re-used. Furthermore, the Kconfig help has been updated and corrected. Signed-off-by: Wolfgang Grandegger Reviewed-by: Wolfram Sang Signed-off-by: Ben Dooks --- drivers/i2c/busses/Kconfig | 7 ++-- drivers/i2c/busses/i2c-mpc.c | 93 +++++++++++++++++++++++++++++++++++--------- 2 files changed, 78 insertions(+), 22 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 10041813c6e..ecf079b7f93 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -419,13 +419,12 @@ config I2C_IXP2000 instead. config I2C_MPC - tristate "MPC107/824x/85xx/52xx/86xx" + tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx" depends on PPC32 help If you say yes to this option, support will be included for the - built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and - MPC85xx/MPC8641 family processors. The driver may also work on 52xx - family processors, though interrupts are known not to work. + built-in I2C interface on the MPC107, Tsi107, MPC512x, MPC52xx, + MPC8240, MPC8245, MPC83xx, MPC85xx and MPC8641 family processors. This driver can also be built as a module. If so, the module will be called i2c-mpc. diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 370c342e5e8..78a15af3294 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -31,6 +31,9 @@ #define DRV_NAME "mpc-i2c" +#define MPC_I2C_CLOCK_LEGACY 0 +#define MPC_I2C_CLOCK_PRESERVE (~0U) + #define MPC_I2C_FDR 0x04 #define MPC_I2C_CR 0x08 #define MPC_I2C_SR 0x0c @@ -163,7 +166,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) return 0; } -#ifdef CONFIG_PPC_MPC52xx +#if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_PPC_MPC512x) static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitconst = { {20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23}, {28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02}, @@ -193,7 +196,7 @@ static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, u32 divider; int i; - if (!clock) + if (clock == MPC_I2C_CLOCK_LEGACY) return -EINVAL; /* Determine divider value */ @@ -221,6 +224,12 @@ static void __devinit mpc_i2c_setup_52xx(struct device_node *node, { int ret, fdr; + if (clock == MPC_I2C_CLOCK_PRESERVE) { + dev_dbg(i2c->dev, "using fdr %d\n", + readb(i2c->base + MPC_I2C_FDR)); + return; + } + ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler); fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */ @@ -229,13 +238,49 @@ static void __devinit mpc_i2c_setup_52xx(struct device_node *node, if (ret >= 0) dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr); } -#else /* !CONFIG_PPC_MPC52xx */ +#else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */ static void __devinit mpc_i2c_setup_52xx(struct device_node *node, struct mpc_i2c *i2c, u32 clock, u32 prescaler) { } -#endif /* CONFIG_PPC_MPC52xx*/ +#endif /* CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x */ + +#ifdef CONFIG_PPC_MPC512x +static void __devinit mpc_i2c_setup_512x(struct device_node *node, + struct mpc_i2c *i2c, + u32 clock, u32 prescaler) +{ + struct device_node *node_ctrl; + void __iomem *ctrl; + const u32 *pval; + u32 idx; + + /* Enable I2C interrupts for mpc5121 */ + node_ctrl = of_find_compatible_node(NULL, NULL, + "fsl,mpc5121-i2c-ctrl"); + if (node_ctrl) { + ctrl = of_iomap(node_ctrl, 0); + if (ctrl) { + /* Interrupt enable bits for i2c-0/1/2: bit 24/26/28 */ + pval = of_get_property(node, "reg", NULL); + idx = (*pval & 0xff) / 0x20; + setbits32(ctrl, 1 << (24 + idx * 2)); + iounmap(ctrl); + } + of_node_put(node_ctrl); + } + + /* The clock setup for the 52xx works also fine for the 512x */ + mpc_i2c_setup_52xx(node, i2c, clock, prescaler); +} +#else /* CONFIG_PPC_MPC512x */ +static void __devinit mpc_i2c_setup_512x(struct device_node *node, + struct mpc_i2c *i2c, + u32 clock, u32 prescaler) +{ +} +#endif /* CONFIG_PPC_MPC512x */ #ifdef CONFIG_FSL_SOC static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] __devinitconst = { @@ -294,7 +339,7 @@ static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, u32 divider; int i; - if (!clock) + if (clock == MPC_I2C_CLOCK_LEGACY) return -EINVAL; /* Determine proper divider value */ @@ -327,6 +372,13 @@ static void __devinit mpc_i2c_setup_8xxx(struct device_node *node, { int ret, fdr; + if (clock == MPC_I2C_CLOCK_PRESERVE) { + dev_dbg(i2c->dev, "using dfsrr %d, fdr %d\n", + readb(i2c->base + MPC_I2C_DFSRR), + readb(i2c->base + MPC_I2C_FDR)); + return; + } + ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler); fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */ @@ -495,7 +547,7 @@ static int __devinit fsl_i2c_probe(struct of_device *op, { struct mpc_i2c *i2c; const u32 *prop; - u32 clock = 0; + u32 clock = MPC_I2C_CLOCK_LEGACY; int result = 0; int plen; @@ -524,20 +576,21 @@ static int __devinit fsl_i2c_probe(struct of_device *op, } } - if (!of_get_property(op->node, "fsl,preserve-clocking", NULL)) { + if (of_get_property(op->node, "fsl,preserve-clocking", NULL)) { + clock = MPC_I2C_CLOCK_PRESERVE; + } else { prop = of_get_property(op->node, "clock-frequency", &plen); if (prop && plen == sizeof(u32)) clock = *prop; + } - if (match->data) { - struct mpc_i2c_data *data = - (struct mpc_i2c_data *)match->data; - data->setup(op->node, i2c, clock, data->prescaler); - } else { - /* Backwards compatibility */ - if (of_get_property(op->node, "dfsrr", NULL)) - mpc_i2c_setup_8xxx(op->node, i2c, clock, 0); - } + if (match->data) { + struct mpc_i2c_data *data = match->data; + data->setup(op->node, i2c, clock, data->prescaler); + } else { + /* Backwards compatibility */ + if (of_get_property(op->node, "dfsrr", NULL)) + mpc_i2c_setup_8xxx(op->node, i2c, clock, 0); } dev_set_drvdata(&op->dev, i2c); @@ -582,6 +635,10 @@ static int __devexit fsl_i2c_remove(struct of_device *op) return 0; }; +static struct mpc_i2c_data mpc_i2c_data_512x __devinitdata = { + .setup = mpc_i2c_setup_512x, +}; + static struct mpc_i2c_data mpc_i2c_data_52xx __devinitdata = { .setup = mpc_i2c_setup_52xx, }; @@ -604,6 +661,7 @@ static const struct of_device_id mpc_i2c_of_match[] = { {.compatible = "mpc5200-i2c", .data = &mpc_i2c_data_52xx, }, {.compatible = "fsl,mpc5200b-i2c", .data = &mpc_i2c_data_52xx, }, {.compatible = "fsl,mpc5200-i2c", .data = &mpc_i2c_data_52xx, }, + {.compatible = "fsl,mpc5121-i2c", .data = &mpc_i2c_data_512x, }, {.compatible = "fsl,mpc8313-i2c", .data = &mpc_i2c_data_8313, }, {.compatible = "fsl,mpc8543-i2c", .data = &mpc_i2c_data_8543, }, {.compatible = "fsl,mpc8544-i2c", .data = &mpc_i2c_data_8544, }, @@ -613,7 +671,6 @@ static const struct of_device_id mpc_i2c_of_match[] = { }; 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, @@ -646,5 +703,5 @@ module_exit(fsl_i2c_exit); MODULE_AUTHOR("Adrian Cox "); MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and " - "MPC824x/85xx/52xx processors"); + "MPC824x/83xx/85xx/86xx/512x/52xx processors"); MODULE_LICENSE("GPL"); -- cgit v1.2.3