From patchwork Wed Sep 12 06:42:12 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ludovic Desroches X-Patchwork-Id: 1441161 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (unknown [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 01C81DF28C for ; Wed, 12 Sep 2012 06:52:06 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TBgfN-00057Q-BS; Wed, 12 Sep 2012 06:43:17 +0000 Received: from eusmtp01.atmel.com ([212.144.249.242]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TBgf5-00051r-O7 for linux-arm-kernel@lists.infradead.org; Wed, 12 Sep 2012 06:43:04 +0000 Received: from ibiza.corp.atmel.com (10.161.101.13) by eusmtp01.atmel.com (10.161.101.30) with Microsoft SMTP Server id 14.2.318.1; Wed, 12 Sep 2012 08:44:37 +0200 From: To: , , Subject: [PATCH v3 3/8] i2c: at91: use an id table for SoC dependent parameters Date: Wed, 12 Sep 2012 08:42:12 +0200 Message-ID: <1347432137-25058-4-git-send-email-ludovic.desroches@atmel.com> X-Mailer: git-send-email 1.7.11.3 In-Reply-To: <1347432137-25058-1-git-send-email-ludovic.desroches@atmel.com> References: <1347432137-25058-1-git-send-email-ludovic.desroches@atmel.com> MIME-Version: 1.0 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -0.3 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: plagnioj@jcrosoft.com, n.voss@weinmann.de, nicolas.ferre@atmel.com, w.sang@pengutronix.de, Ludovic Desroches X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Ludovic Desroches Use the id_table to store configuration structures which are depending on SoC. Signed-off-by: Ludovic Desroches Acked-by: Nikolaus Voss Acked-by: Nicolas Ferre --- arch/arm/mach-at91/at91rm9200.c | 2 +- arch/arm/mach-at91/at91rm9200_devices.c | 11 +---- arch/arm/mach-at91/at91sam9260.c | 3 +- arch/arm/mach-at91/at91sam9260_devices.c | 8 ++- arch/arm/mach-at91/at91sam9261.c | 3 +- arch/arm/mach-at91/at91sam9261_devices.c | 17 +++---- arch/arm/mach-at91/at91sam9263.c | 2 +- arch/arm/mach-at91/at91sam9263_devices.c | 2 +- arch/arm/mach-at91/at91sam9g45.c | 4 +- arch/arm/mach-at91/at91sam9g45_devices.c | 4 +- arch/arm/mach-at91/at91sam9rl.c | 4 +- arch/arm/mach-at91/at91sam9rl_devices.c | 2 +- drivers/i2c/busses/i2c-at91.c | 85 +++++++++++++++++++++++++------- 13 files changed, 95 insertions(+), 52 deletions(-) diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index f2112f9..b4f0565 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -187,7 +187,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), - CLKDEV_CON_DEV_ID(NULL, "at91_i2c", &twi_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200", &twi_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), CLKDEV_CON_ID("pioA", &pioA_clk), diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 71e7387..0b972f2 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -494,18 +494,9 @@ static struct resource twi_resources[] = { }, }; -static const struct platform_device_id twi_ip_type = { - /* - * driver_data is 1 for RM9200 compatible ip, see enum twi_ip_id in - * drivers/i2c/busses/i2c-at91.c - */ - .driver_data = 1, -}; - static struct platform_device at91rm9200_twi_device = { - .name = "at91_i2c", + .name = "i2c-at91rm9200", .id = -1, - .id_entry = &twi_ip_type, .resource = twi_resources, .num_resources = ARRAY_SIZE(twi_resources), }; diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 57c79ee..5bd19a4 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -211,7 +211,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), - CLKDEV_CON_DEV_ID(NULL, "at91_i2c", &twi_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260", &twi_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20", &twi_clk), /* more usart lookup table for DT entries */ CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk), diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index bce572a..95fc23a 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -503,7 +503,6 @@ static struct resource twi_resources[] = { }; static struct platform_device at91sam9260_twi_device = { - .name = "at91_i2c", .id = -1, .resource = twi_resources, .num_resources = ARRAY_SIZE(twi_resources), @@ -511,6 +510,13 @@ static struct platform_device at91sam9260_twi_device = { void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) { + /* IP version is not the same on 9260 and g20 */ + if (cpu_is_at91sam9g20()) { + at91sam9260_twi_device.name = "i2c-at91sam9g20"; + } else { + at91sam9260_twi_device.name = "i2c-at91sam9260"; + } + /* pins used for TWI interface */ at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */ at91_set_multi_drive(AT91_PIN_PA23, 1); diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 71ca1e0..8d999eb 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -178,7 +178,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0), - CLKDEV_CON_DEV_ID(NULL, "at91_i2c", &twi_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261", &twi_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10", &twi_clk), CLKDEV_CON_ID("pioA", &pioA_clk), CLKDEV_CON_ID("pioB", &pioB_clk), CLKDEV_CON_ID("pioC", &pioC_clk), diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 3b44731..29188ef 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -316,24 +316,21 @@ static struct resource twi_resources[] = { }, }; -static const struct platform_device_id twi_ip_type = { - /* - * driver_data is 2 for SAM9261 compatible ip, see enum twi_ip_id in - * drivers/i2c/busses/i2c-at91.c - */ - .driver_data = 2, -}; - static struct platform_device at91sam9261_twi_device = { - .name = "at91_i2c", .id = -1, - .id_entry = &twi_ip_type, .resource = twi_resources, .num_resources = ARRAY_SIZE(twi_resources), }; void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) { + /* IP version is not the same on 9261 and g10 */ + if (cpu_is_at91sam9g10()) { + at91sam9261_twi_device.name = "i2c-at91sam9g10"; + } else { + at91sam9261_twi_device.name = "i2c-at91sam9261"; + } + /* pins used for TWI interface */ at91_set_A_periph(AT91_PIN_PA7, 0); /* TWD */ at91_set_multi_drive(AT91_PIN_PA7, 1); diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 2a08305..e6b5956 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -193,7 +193,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), - CLKDEV_CON_DEV_ID(NULL, "at91_i2c", &twi_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260", &twi_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), CLKDEV_CON_ID("pioA", &pioA_clk), diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 9b6ca73..3f5288e 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -574,7 +574,7 @@ static struct resource twi_resources[] = { }; static struct platform_device at91sam9263_twi_device = { - .name = "at91_i2c", + .name = "i2c-at91sam9260", .id = -1, .resource = twi_resources, .num_resources = ARRAY_SIZE(twi_resources), diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index ddf3d37..858f032 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -237,8 +237,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb0_clk), CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk), - CLKDEV_CON_DEV_ID(NULL, "at91_i2c.0", &twi0_clk), - CLKDEV_CON_DEV_ID(NULL, "at91_i2c.1", &twi1_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi0_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.1", &twi1_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), CLKDEV_CON_DEV_ID(NULL, "atmel-trng", &trng_clk), diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index b5a6cb9..0fcd871 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -653,7 +653,7 @@ static struct resource twi0_resources[] = { }; static struct platform_device at91sam9g45_twi0_device = { - .name = "at91_i2c", + .name = "i2c-at91sam9g10", .id = 0, .resource = twi0_resources, .num_resources = ARRAY_SIZE(twi0_resources), @@ -673,7 +673,7 @@ static struct resource twi1_resources[] = { }; static struct platform_device at91sam9g45_twi1_device = { - .name = "at91_i2c", + .name = "i2c-at91sam9g10", .id = 1, .resource = twi1_resources, .num_resources = ARRAY_SIZE(twi1_resources), diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index bf79c1f..72e9084 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -186,8 +186,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), - CLKDEV_CON_DEV_ID(NULL, "at91_i2c.0", &twi0_clk), - CLKDEV_CON_DEV_ID(NULL, "at91_i2c.1", &twi1_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi0_clk), + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.1", &twi1_clk), CLKDEV_CON_ID("pioA", &pioA_clk), CLKDEV_CON_ID("pioB", &pioB_clk), CLKDEV_CON_ID("pioC", &pioC_clk), diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index b3d365d..0794954 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -346,7 +346,7 @@ static struct resource twi_resources[] = { }; static struct platform_device at91sam9rl_twi_device = { - .name = "at91_i2c", + .name = "i2c-at91sam9g20", .id = -1, .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 08aaee7..78bcad0 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -61,10 +61,10 @@ #define AT91_TWI_RHR 0x0030 /* Receive Holding Register */ #define AT91_TWI_THR 0x0034 /* Transmit Holding Register */ -enum twi_ip_id { - DEFAULT = 0, /* default ip, no known limitations */ - RM9200 = 1, - SAM9261 = 2, +struct at91_twi_pdata { + unsigned clk_max_div; + unsigned clk_offset; + bool has_unre_flag; }; struct at91_twi_dev { @@ -78,8 +78,8 @@ struct at91_twi_dev { int irq; unsigned transfer_status; struct i2c_adapter adapter; - enum twi_ip_id ip_id; unsigned twi_cwgr_reg; + struct at91_twi_pdata *pdata; }; static unsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg) @@ -114,16 +114,9 @@ static void at91_init_twi_bus(struct at91_twi_dev *dev) static void __devinit at91_calc_twi_clock(struct at91_twi_dev *dev, int twi_clk) { int ckdiv, cdiv, div; - int offset = 4; - int max_ckdiv = 7; - - if (dev->ip_id == RM9200) { - offset = 3; - max_ckdiv = 5; - } else if (dev->ip_id == SAM9261) { - offset = 4; - max_ckdiv = 5; - } + struct at91_twi_pdata *pdata = dev->pdata; + int offset = pdata->clk_offset; + int max_ckdiv = pdata->clk_max_div; div = max(0, (int)DIV_ROUND_UP(clk_get_rate(dev->clk), 2 * twi_clk) - offset); @@ -209,6 +202,7 @@ static irqreturn_t atmel_twi_interrupt(int irq, void *dev_id) static int at91_do_twi_transfer(struct at91_twi_dev *dev) { int ret; + bool has_unre_flag = dev->pdata->has_unre_flag; dev_dbg(dev->dev, "transfer: %s %d bytes.\n", (dev->msg->flags & I2C_M_RD) ? "read" : "write", dev->buf_len); @@ -250,7 +244,7 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) dev_err(dev->dev, "overrun while reading\n"); return -EIO; } - if (dev->transfer_status & AT91_TWI_UNRE && dev->ip_id == RM9200) { + if (has_unre_flag && dev->transfer_status & AT91_TWI_UNRE) { dev_err(dev->dev, "underrun while writing\n"); return -EIO; } @@ -323,6 +317,57 @@ static struct i2c_algorithm at91_twi_algorithm = { .functionality = at91_twi_func, }; +static struct at91_twi_pdata at91rm9200_config = { + .clk_max_div = 5, + .clk_offset = 3, + .has_unre_flag = true, +}; + +static struct at91_twi_pdata at91sam9261_config = { + .clk_max_div = 5, + .clk_offset = 4, + .has_unre_flag = false, +}; + +static struct at91_twi_pdata at91sam9260_config = { + .clk_max_div = 7, + .clk_offset = 4, + .has_unre_flag = false, +}; + +static struct at91_twi_pdata at91sam9g20_config = { + .clk_max_div = 7, + .clk_offset = 4, + .has_unre_flag = false, +}; + +static struct at91_twi_pdata at91sam9g10_config = { + .clk_max_div = 7, + .clk_offset = 4, + .has_unre_flag = false, +}; + +static const struct platform_device_id at91_twi_devtypes[] = { + { + .name = "i2c-at91rm9200", + .driver_data = (unsigned long) &at91rm9200_config, + }, { + .name = "i2c-at91sam9261", + .driver_data = (unsigned long) &at91sam9261_config, + }, { + .name = "i2c-at91sam9260", + .driver_data = (unsigned long) &at91sam9260_config, + }, { + .name = "i2c-at91sam9g20", + .driver_data = (unsigned long) &at91sam9g20_config, + }, { + .name = "i2c-at91sam9g10", + .driver_data = (unsigned long) &at91sam9g10_config, + }, { + /* sentinel */ + } +}; + static int __devinit at91_twi_probe(struct platform_device *pdev) { struct at91_twi_dev *dev; @@ -339,6 +384,10 @@ static int __devinit at91_twi_probe(struct platform_device *pdev) if (!mem) return -ENODEV; + dev->pdata = at91_twi_get_driver_data(pdev); + if (!dev->pdata) + return -ENODEV; + dev->base = devm_request_and_ioremap(&pdev->dev, mem); if (!dev->base) return -EBUSY; @@ -354,9 +403,6 @@ static int __devinit at91_twi_probe(struct platform_device *pdev) return rc; } - if (pdev->id_entry) - dev->ip_id = pdev->id_entry->driver_data; - platform_set_drvdata(pdev, dev); dev->clk = devm_clk_get(dev->dev, NULL); @@ -432,6 +478,7 @@ static const struct dev_pm_ops at91_twi_pm = { static struct platform_driver at91_twi_driver = { .probe = at91_twi_probe, .remove = __devexit_p(at91_twi_remove), + .id_table = at91_twi_devtypes, .driver = { .name = "at91_i2c", .owner = THIS_MODULE,