The twi IP of AT91RM9200 has a bug which limits ckdiv to be less than or equal to 5. Previously, this was checked in the driver with cpu_is_rm9200(). This patch moves this information into the platform_device as suggested by Arnd Bergmann. Signed-off-by: Nikolaus Voss <n.voss@xxxxxxxxxxx> --- arch/arm/mach-at91/at91cap9_devices.c | 9 +++++++++ arch/arm/mach-at91/at91rm9200_devices.c | 9 +++++++++ arch/arm/mach-at91/at91sam9260_devices.c | 9 +++++++++ arch/arm/mach-at91/at91sam9261_devices.c | 9 +++++++++ arch/arm/mach-at91/at91sam9263_devices.c | 9 +++++++++ arch/arm/mach-at91/at91sam9g45_devices.c | 10 ++++++++++ arch/arm/mach-at91/at91sam9rl_devices.c | 9 +++++++++ drivers/i2c/busses/i2c-at91.c | 7 ++++--- 8 files changed, 68 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index adad70d..495fd24 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -496,9 +496,18 @@ static struct resource twi_resources[] = { }, }; +static const struct platform_device_id twi_id = { + /* + * driver_data is "1" for hardware with ckdiv upper limit == 5 + * (AT91RM9200 erratum 22), "0" for twi modules without this bug + */ + .driver_data = 0, +}; + static struct platform_device at91cap9_twi_device = { .name = "at91_i2c", .id = -1, + .id_entry = &twi_id, .resource = twi_resources, .num_resources = ARRAY_SIZE(twi_resources), }; diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 66591fa..8db7383 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -493,9 +493,18 @@ static struct resource twi_resources[] = { }, }; +static const struct platform_device_id twi_id = { + /* + * driver_data is "1" for hardware with ckdiv upper limit == 5 + * (AT91RM9200 erratum 22), "0" for twi modules without this bug + */ + .driver_data = 1, +}; + static struct platform_device at91rm9200_twi_device = { .name = "at91_i2c", .id = -1, + .id_entry = &twi_id, .resource = twi_resources, .num_resources = ARRAY_SIZE(twi_resources), }; diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 25e3464..1e9a075 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -498,9 +498,18 @@ static struct resource twi_resources[] = { }, }; +static const struct platform_device_id twi_id = { + /* + * driver_data is "1" for hardware with ckdiv upper limit == 5 + * (AT91RM9200 erratum 22), "0" for twi modules without this bug + */ + .driver_data = 0, +}; + static struct platform_device at91sam9260_twi_device = { .name = "at91_i2c", .id = -1, + .id_entry = &twi_id, .resource = twi_resources, .num_resources = ARRAY_SIZE(twi_resources), }; diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index ae78f4d..16f22b7 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -315,9 +315,18 @@ static struct resource twi_resources[] = { }, }; +static const struct platform_device_id twi_id = { + /* + * driver_data is "1" for hardware with ckdiv upper limit == 5 + * (AT91RM9200 erratum 22), "0" for twi modules without this bug + */ + .driver_data = 0, +}; + static struct platform_device at91sam9261_twi_device = { .name = "at91_i2c", .id = -1, + .id_entry = &twi_id, .resource = twi_resources, .num_resources = ARRAY_SIZE(twi_resources), }; diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index ad017eb..346d258 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -571,9 +571,18 @@ static struct resource twi_resources[] = { }, }; +static const struct platform_device_id twi_id = { + /* + * driver_data is "1" for hardware with ckdiv upper limit == 5 + * (AT91RM9200 erratum 22), "0" for twi modules without this bug + */ + .driver_data = 0, +}; + static struct platform_device at91sam9263_twi_device = { .name = "at91_i2c", .id = -1, + .id_entry = &twi_id, .resource = twi_resources, .num_resources = ARRAY_SIZE(twi_resources), }; diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 8743b14..5916f0e 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -650,9 +650,18 @@ static struct resource twi0_resources[] = { }, }; +static const struct platform_device_id twi_id = { + /* + * driver_data is "1" for hardware with ckdiv upper limit == 5 + * (AT91RM9200 erratum 22), "0" for twi modules without this bug + */ + .driver_data = 0, +}; + static struct platform_device at91sam9g45_twi0_device = { .name = "at91_i2c", .id = 0, + .id_entry = &twi_id, .resource = twi0_resources, .num_resources = ARRAY_SIZE(twi0_resources), }; @@ -673,6 +682,7 @@ static struct resource twi1_resources[] = { static struct platform_device at91sam9g45_twi1_device = { .name = "at91_i2c", .id = 1, + .id_entry = &twi_id, .resource = twi1_resources, .num_resources = ARRAY_SIZE(twi1_resources), }; diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 628eb56..bec28b5 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -350,9 +350,18 @@ static struct resource twi_resources[] = { }, }; +static const struct platform_device_id twi_id = { + /* + * driver_data is "1" for hardware with ckdiv upper limit == 5 + * (AT91RM9200 erratum 22), "0" for twi modules without this bug + */ + .driver_data = 0, +}; + static struct platform_device at91sam9rl_twi_device = { .name = "at91_i2c", .id = -1, + .id_entry = &twi_id, .resource = twi_resources, .num_resources = ARRAY_SIZE(twi_resources), }; diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index 34deef4..4364dd1 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -27,8 +27,6 @@ #include <linux/platform_device.h> #include <linux/slab.h> -#include <mach/cpu.h> - #define TWI_CLK_HZ 100000 /* max 400 Kbits/s */ #define AT91_I2C_TIMEOUT msecs_to_jiffies(100) /* transfer timeout */ @@ -74,6 +72,7 @@ struct at91_twi_dev { int irq; unsigned transfer_status; struct i2c_adapter adapter; + bool has_ckdiv_limit_bug; }; static unsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg) @@ -110,7 +109,7 @@ static void __devinit at91_set_twi_clock(struct at91_twi_dev *dev, int twi_clk) int ckdiv = fls(div >> 8); const int cdiv = div >> ckdiv; - if (cpu_is_at91rm9200() && (ckdiv > 5)) { + if (dev->has_ckdiv_limit_bug && (ckdiv > 5)) { dev_warn(dev->dev, "AT91RM9200 erratum 22: using ckdiv = 5.\n"); ckdiv = 5; } @@ -314,6 +313,8 @@ static int __devinit at91_twi_probe(struct platform_device *pdev) goto err_release_region; } + dev->has_ckdiv_limit_bug = pdev->id_entry->driver_data == 1; + init_completion(&dev->cmd_complete); dev->dev = &pdev->dev; -- 1.7.5.4 -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html