From patchwork Tue Nov 9 16:16:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rob Herring (Arm)" X-Patchwork-Id: 12610859 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3EEE6C433F5 for ; Tue, 9 Nov 2021 16:16:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 26F3E60FD8 for ; Tue, 9 Nov 2021 16:16:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239468AbhKIQTI (ORCPT ); Tue, 9 Nov 2021 11:19:08 -0500 Received: from mail-ot1-f51.google.com ([209.85.210.51]:42639 "EHLO mail-ot1-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230334AbhKIQTH (ORCPT ); Tue, 9 Nov 2021 11:19:07 -0500 Received: by mail-ot1-f51.google.com with SMTP id g91-20020a9d12e4000000b0055ae68cfc3dso28869300otg.9; Tue, 09 Nov 2021 08:16:21 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=jdrgxIgEzKrmMk735DkPidLrZORkq7ypaLQEh4/MLAg=; b=vFSjgq6ifpIC91fN9cgOOcsrq9Nc4TvNV2cl9fwTmCf2/rZSibyvr3J1iOgNiFVtnS 3bclhX/jFRVOYeJn8PT3WekcLU2P4X6Pp+gGFgbhJo+GETP5hMtpBaW2rYNs+85F69zS peEQ9sJCl31+4G2OY8UDi35jYH+jlPYZnMzPTJtkZcnK9ClP1h2N0KEWzz6TarB6wcv7 NCYU8zbwA876qKmZx1GedOBxJM3h1U/KMBrV5BtE9CC0A0QT693byCQR1NK3EkslLRa2 tYP8yJISeb97KBgHodqIj+oZqFlxlLWDtEQHJFxk04H1/PippIPr3nc0KEbetKjcHGUd 2i+Q== X-Gm-Message-State: AOAM530vTxCsOfC9Gbm9VpT2c0JrdfAjNt78LQabtSBmLMIdWahuQTUM 5kEacTtzmo6fH1GOf44brjr3RvkYaw== X-Google-Smtp-Source: ABdhPJx5paQeA7EMGcTnVq36aOpDr1x3ukMEDilCqgp63O7QfuU8otNG1WVqDiSL9yguQi6genpGYA== X-Received: by 2002:a05:6830:1e6d:: with SMTP id m13mr6952498otr.304.1636474581451; Tue, 09 Nov 2021 08:16:21 -0800 (PST) Received: from xps15.herring.priv (66-90-148-213.dyn.grandenetworks.net. [66.90.148.213]) by smtp.googlemail.com with ESMTPSA id m12sm4146662ots.59.2021.11.09.08.16.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Nov 2021 08:16:20 -0800 (PST) From: Rob Herring To: Wolfram Sang Cc: linux-kernel@vger.kernel.org, Thomas Bogendoerfer , linux-mips@vger.kernel.org, George Cherian , linux-i2c@vger.kernel.org Subject: [PATCH 1/2] i2c: Remove Netlogic XLP variant Date: Tue, 9 Nov 2021 10:16:18 -0600 Message-Id: <20211109161619.2206494-1-robh@kernel.org> X-Mailer: git-send-email 2.32.0 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Netlogic XLP was removed in commit 95b8a5e0111a ("MIPS: Remove NETLOGIC support"). With those gone, the single platform left to support is Cavium ThunderX2. Remove the Netlogic variant and DT support. For simplicity, the existing kconfig name is retained. Cc: George Cherian Cc: linux-i2c@vger.kernel.org Signed-off-by: Rob Herring --- drivers/i2c/busses/Kconfig | 6 +++--- drivers/i2c/busses/i2c-xlp9xx.c | 7 ------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index dce392839017..e9dd1640ffde 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -1170,11 +1170,11 @@ config I2C_XLR will be called i2c-xlr. config I2C_XLP9XX - tristate "XLP9XX I2C support" - depends on CPU_XLP || ARCH_THUNDER2 || COMPILE_TEST + tristate "Cavium ThunderX2 I2C support" + depends on ARCH_THUNDER2 || COMPILE_TEST help This driver enables support for the on-chip I2C interface of - the Broadcom XLP9xx/XLP5xx MIPS and Vulcan ARM64 processors. + the Cavium ThunderX2 processors. (Originally on Netlogic XLP SoCs.) This driver can also be built as a module. If so, the module will be called i2c-xlp9xx. diff --git a/drivers/i2c/busses/i2c-xlp9xx.c b/drivers/i2c/busses/i2c-xlp9xx.c index 6d24dc385522..4e3b11c0f732 100644 --- a/drivers/i2c/busses/i2c-xlp9xx.c +++ b/drivers/i2c/busses/i2c-xlp9xx.c @@ -572,12 +572,6 @@ static int xlp9xx_i2c_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id xlp9xx_i2c_of_match[] = { - { .compatible = "netlogic,xlp980-i2c", }, - { /* sentinel */ }, -}; -MODULE_DEVICE_TABLE(of, xlp9xx_i2c_of_match); - #ifdef CONFIG_ACPI static const struct acpi_device_id xlp9xx_i2c_acpi_ids[] = { {"BRCM9007", 0}, @@ -592,7 +586,6 @@ static struct platform_driver xlp9xx_i2c_driver = { .remove = xlp9xx_i2c_remove, .driver = { .name = "xlp9xx-i2c", - .of_match_table = xlp9xx_i2c_of_match, .acpi_match_table = ACPI_PTR(xlp9xx_i2c_acpi_ids), }, }; From patchwork Tue Nov 9 16:16:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rob Herring (Arm)" X-Patchwork-Id: 12610861 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F143DC433EF for ; Tue, 9 Nov 2021 16:16:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D861E611CA for ; Tue, 9 Nov 2021 16:16:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239529AbhKIQTK (ORCPT ); Tue, 9 Nov 2021 11:19:10 -0500 Received: from mail-oi1-f178.google.com ([209.85.167.178]:45854 "EHLO mail-oi1-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239499AbhKIQTJ (ORCPT ); Tue, 9 Nov 2021 11:19:09 -0500 Received: by mail-oi1-f178.google.com with SMTP id u2so34514541oiu.12; Tue, 09 Nov 2021 08:16:23 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LTgw7u3B1rnQ2mPJkbUOilZFND3zAdrIE5Vn3ipd39w=; b=KFjAquTr8LP9VZsLBcIhKg3QJcD75HHcqzd/y049h1V+W8VUNifpy0TCB31d/R0nIP 30YRtwOaDYSfkzdRyIXEIoa44f7Rrw1NUU5uppeTcFMKyG/QJ8RHMm9Ete9PCKmMGPAl vDrrgkq8mg5uuUou3A95iZHBf6ntuTDn9qGc0fxdFeQ8f7HCR3c5WOQve7Su10JjVyoR K4xMu7kRiOkNMeYVbaht0As1DdQj0tqSKvLgqieH3cvjgfM1inSrnCUwqcNplxq0LKXL Qg1832nRfdlO7wu1qTSGClfO2J7d1fhzdjnj8mnbfID45a85I2+ahvxbSSRKPZ14kNvD T3TQ== X-Gm-Message-State: AOAM533i1ZRTXcl9d8Z9ft7wGnWTi8ercO+M/cf96skoshnwtgfGvOxu wYvXL5Xg+onAvL9oPTXomw== X-Google-Smtp-Source: ABdhPJzDDFWYLwvKmNGx1BBsEOS/TKCOHJ8g1FCMoLafQBLduR4m5yoNQ+gozXggyMA/AHSAr4ffaQ== X-Received: by 2002:a54:4397:: with SMTP id u23mr6677303oiv.112.1636474582748; Tue, 09 Nov 2021 08:16:22 -0800 (PST) Received: from xps15.herring.priv (66-90-148-213.dyn.grandenetworks.net. [66.90.148.213]) by smtp.googlemail.com with ESMTPSA id m12sm4146662ots.59.2021.11.09.08.16.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Nov 2021 08:16:22 -0800 (PST) From: Rob Herring To: Wolfram Sang Cc: linux-kernel@vger.kernel.org, Thomas Bogendoerfer , linux-mips@vger.kernel.org, George Cherian , linux-i2c@vger.kernel.org Subject: [PATCH 2/2] i2c: Remove unused Netlogic/Sigma Designs XLR driver Date: Tue, 9 Nov 2021 10:16:19 -0600 Message-Id: <20211109161619.2206494-2-robh@kernel.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211109161619.2206494-1-robh@kernel.org> References: <20211109161619.2206494-1-robh@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org Commits 95b8a5e0111a ("MIPS: Remove NETLOGIC support") and edd4488aea9c ("ARM: remove tango platform") removed Netlogic XLR and Sigma Designs Tango platforms which means there are no platforms using the XLR I2C driver and it can be removed. Cc: linux-i2c@vger.kernel.org Signed-off-by: Rob Herring --- drivers/i2c/busses/Kconfig | 10 - drivers/i2c/busses/Makefile | 1 - drivers/i2c/busses/i2c-xlr.c | 470 ----------------------------------- 3 files changed, 481 deletions(-) delete mode 100644 drivers/i2c/busses/i2c-xlr.c diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index e9dd1640ffde..2f0a440ec446 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -1159,16 +1159,6 @@ config I2C_XILINX This driver can also be built as a module. If so, the module will be called xilinx_i2c. -config I2C_XLR - tristate "Netlogic XLR I2C support" - depends on CPU_XLR || COMPILE_TEST - help - This driver enables support for the on-chip I2C interface of - the Netlogic XLR/XLS MIPS processors and Sigma Designs SOCs. - - This driver can also be built as a module. If so, the module - will be called i2c-xlr. - config I2C_XLP9XX tristate "Cavium ThunderX2 I2C support" depends on ARCH_THUNDER2 || COMPILE_TEST diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index d85899fef8c7..1d00dce77098 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -119,7 +119,6 @@ obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o i2c-thunderx-objs := i2c-octeon-core.o i2c-thunderx-pcidrv.o obj-$(CONFIG_I2C_THUNDERX) += i2c-thunderx.o obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o -obj-$(CONFIG_I2C_XLR) += i2c-xlr.o obj-$(CONFIG_I2C_XLP9XX) += i2c-xlp9xx.o obj-$(CONFIG_I2C_RCAR) += i2c-rcar.o diff --git a/drivers/i2c/busses/i2c-xlr.c b/drivers/i2c/busses/i2c-xlr.c deleted file mode 100644 index 9ce20652d494..000000000000 --- a/drivers/i2c/busses/i2c-xlr.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Copyright 2011, Netlogic Microsystems Inc. - * Copyright 2004, Matt Porter - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* XLR I2C REGISTERS */ -#define XLR_I2C_CFG 0x00 -#define XLR_I2C_CLKDIV 0x01 -#define XLR_I2C_DEVADDR 0x02 -#define XLR_I2C_ADDR 0x03 -#define XLR_I2C_DATAOUT 0x04 -#define XLR_I2C_DATAIN 0x05 -#define XLR_I2C_STATUS 0x06 -#define XLR_I2C_STARTXFR 0x07 -#define XLR_I2C_BYTECNT 0x08 -#define XLR_I2C_HDSTATIM 0x09 - -/* Sigma Designs additional registers */ -#define XLR_I2C_INT_EN 0x09 -#define XLR_I2C_INT_STAT 0x0a - -/* XLR I2C REGISTERS FLAGS */ -#define XLR_I2C_BUS_BUSY 0x01 -#define XLR_I2C_SDOEMPTY 0x02 -#define XLR_I2C_RXRDY 0x04 -#define XLR_I2C_ACK_ERR 0x08 -#define XLR_I2C_ARB_STARTERR 0x30 - -/* Register Values */ -#define XLR_I2C_CFG_ADDR 0xF8 -#define XLR_I2C_CFG_NOADDR 0xFA -#define XLR_I2C_STARTXFR_ND 0x02 /* No Data */ -#define XLR_I2C_STARTXFR_RD 0x01 /* Read */ -#define XLR_I2C_STARTXFR_WR 0x00 /* Write */ - -#define XLR_I2C_TIMEOUT 10 /* timeout per byte in msec */ - -/* - * On XLR/XLS, we need to use __raw_ IO to read the I2C registers - * because they are in the big-endian MMIO area on the SoC. - * - * The readl/writel implementation on XLR/XLS byteswaps, because - * those are for its little-endian PCI space (see arch/mips/Kconfig). - */ -static inline void xlr_i2c_wreg(u32 __iomem *base, unsigned int reg, u32 val) -{ - __raw_writel(val, base + reg); -} - -static inline u32 xlr_i2c_rdreg(u32 __iomem *base, unsigned int reg) -{ - return __raw_readl(base + reg); -} - -#define XLR_I2C_FLAG_IRQ 1 - -struct xlr_i2c_config { - u32 flags; /* optional feature support */ - u32 status_busy; /* value of STATUS[0] when busy */ - u32 cfg_extra; /* extra CFG bits to set */ -}; - -struct xlr_i2c_private { - struct i2c_adapter adap; - u32 __iomem *iobase; - int irq; - int pos; - struct i2c_msg *msg; - const struct xlr_i2c_config *cfg; - wait_queue_head_t wait; - struct clk *clk; -}; - -static int xlr_i2c_busy(struct xlr_i2c_private *priv, u32 status) -{ - return (status & XLR_I2C_BUS_BUSY) == priv->cfg->status_busy; -} - -static int xlr_i2c_idle(struct xlr_i2c_private *priv) -{ - return !xlr_i2c_busy(priv, xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS)); -} - -static int xlr_i2c_wait(struct xlr_i2c_private *priv, unsigned long timeout) -{ - int status; - int t; - - t = wait_event_timeout(priv->wait, xlr_i2c_idle(priv), - msecs_to_jiffies(timeout)); - if (!t) - return -ETIMEDOUT; - - status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS); - - return status & XLR_I2C_ACK_ERR ? -EIO : 0; -} - -static void xlr_i2c_tx_irq(struct xlr_i2c_private *priv, u32 status) -{ - struct i2c_msg *msg = priv->msg; - - if (status & XLR_I2C_SDOEMPTY) - xlr_i2c_wreg(priv->iobase, XLR_I2C_DATAOUT, - msg->buf[priv->pos++]); -} - -static void xlr_i2c_rx_irq(struct xlr_i2c_private *priv, u32 status) -{ - struct i2c_msg *msg = priv->msg; - - if (status & XLR_I2C_RXRDY) - msg->buf[priv->pos++] = - xlr_i2c_rdreg(priv->iobase, XLR_I2C_DATAIN); -} - -static irqreturn_t xlr_i2c_irq(int irq, void *dev_id) -{ - struct xlr_i2c_private *priv = dev_id; - struct i2c_msg *msg = priv->msg; - u32 int_stat, status; - - int_stat = xlr_i2c_rdreg(priv->iobase, XLR_I2C_INT_STAT); - if (!int_stat) - return IRQ_NONE; - - xlr_i2c_wreg(priv->iobase, XLR_I2C_INT_STAT, int_stat); - - if (!msg) - return IRQ_HANDLED; - - status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS); - - if (priv->pos < msg->len) { - if (msg->flags & I2C_M_RD) - xlr_i2c_rx_irq(priv, status); - else - xlr_i2c_tx_irq(priv, status); - } - - if (!xlr_i2c_busy(priv, status)) - wake_up(&priv->wait); - - return IRQ_HANDLED; -} - -static int xlr_i2c_tx(struct xlr_i2c_private *priv, u16 len, - u8 *buf, u16 addr) -{ - struct i2c_adapter *adap = &priv->adap; - unsigned long timeout, stoptime, checktime; - u32 i2c_status; - int pos, timedout; - u8 offset; - u32 xfer; - - offset = buf[0]; - xlr_i2c_wreg(priv->iobase, XLR_I2C_ADDR, offset); - xlr_i2c_wreg(priv->iobase, XLR_I2C_DEVADDR, addr); - xlr_i2c_wreg(priv->iobase, XLR_I2C_CFG, - XLR_I2C_CFG_ADDR | priv->cfg->cfg_extra); - - timeout = msecs_to_jiffies(XLR_I2C_TIMEOUT); - stoptime = jiffies + timeout; - timedout = 0; - - if (len == 1) { - xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len - 1); - xfer = XLR_I2C_STARTXFR_ND; - pos = 1; - } else { - xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len - 2); - xlr_i2c_wreg(priv->iobase, XLR_I2C_DATAOUT, buf[1]); - xfer = XLR_I2C_STARTXFR_WR; - pos = 2; - } - - priv->pos = pos; - -retry: - /* retry can only happen on the first byte */ - xlr_i2c_wreg(priv->iobase, XLR_I2C_STARTXFR, xfer); - - if (priv->irq > 0) - return xlr_i2c_wait(priv, XLR_I2C_TIMEOUT * len); - - while (!timedout) { - checktime = jiffies; - i2c_status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS); - - if ((i2c_status & XLR_I2C_SDOEMPTY) && pos < len) { - xlr_i2c_wreg(priv->iobase, XLR_I2C_DATAOUT, buf[pos++]); - - /* reset timeout on successful xmit */ - stoptime = jiffies + timeout; - } - timedout = time_after(checktime, stoptime); - - if (i2c_status & XLR_I2C_ARB_STARTERR) { - if (timedout) - break; - goto retry; - } - - if (i2c_status & XLR_I2C_ACK_ERR) - return -EIO; - - if (!xlr_i2c_busy(priv, i2c_status) && pos >= len) - return 0; - } - dev_err(&adap->dev, "I2C transmit timeout\n"); - return -ETIMEDOUT; -} - -static int xlr_i2c_rx(struct xlr_i2c_private *priv, u16 len, u8 *buf, u16 addr) -{ - struct i2c_adapter *adap = &priv->adap; - u32 i2c_status; - unsigned long timeout, stoptime, checktime; - int nbytes, timedout; - - xlr_i2c_wreg(priv->iobase, XLR_I2C_CFG, - XLR_I2C_CFG_NOADDR | priv->cfg->cfg_extra); - xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len - 1); - xlr_i2c_wreg(priv->iobase, XLR_I2C_DEVADDR, addr); - - priv->pos = 0; - - timeout = msecs_to_jiffies(XLR_I2C_TIMEOUT); - stoptime = jiffies + timeout; - timedout = 0; - nbytes = 0; -retry: - xlr_i2c_wreg(priv->iobase, XLR_I2C_STARTXFR, XLR_I2C_STARTXFR_RD); - - if (priv->irq > 0) - return xlr_i2c_wait(priv, XLR_I2C_TIMEOUT * len); - - while (!timedout) { - checktime = jiffies; - i2c_status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS); - if (i2c_status & XLR_I2C_RXRDY) { - if (nbytes >= len) - return -EIO; /* should not happen */ - - buf[nbytes++] = - xlr_i2c_rdreg(priv->iobase, XLR_I2C_DATAIN); - - /* reset timeout on successful read */ - stoptime = jiffies + timeout; - } - - timedout = time_after(checktime, stoptime); - if (i2c_status & XLR_I2C_ARB_STARTERR) { - if (timedout) - break; - goto retry; - } - - if (i2c_status & XLR_I2C_ACK_ERR) - return -EIO; - - if (!xlr_i2c_busy(priv, i2c_status)) - return 0; - } - - dev_err(&adap->dev, "I2C receive timeout\n"); - return -ETIMEDOUT; -} - -static int xlr_i2c_xfer(struct i2c_adapter *adap, - struct i2c_msg *msgs, int num) -{ - struct i2c_msg *msg; - int i; - int ret = 0; - struct xlr_i2c_private *priv = i2c_get_adapdata(adap); - - ret = clk_enable(priv->clk); - if (ret) - return ret; - - if (priv->irq) - xlr_i2c_wreg(priv->iobase, XLR_I2C_INT_EN, 0xf); - - - for (i = 0; ret == 0 && i < num; i++) { - msg = &msgs[i]; - priv->msg = msg; - if (msg->flags & I2C_M_RD) - ret = xlr_i2c_rx(priv, msg->len, &msg->buf[0], - msg->addr); - else - ret = xlr_i2c_tx(priv, msg->len, &msg->buf[0], - msg->addr); - } - - if (priv->irq) - xlr_i2c_wreg(priv->iobase, XLR_I2C_INT_EN, 0); - - clk_disable(priv->clk); - priv->msg = NULL; - - return (ret != 0) ? ret : num; -} - -static u32 xlr_func(struct i2c_adapter *adap) -{ - /* Emulate SMBUS over I2C */ - return (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) | I2C_FUNC_I2C; -} - -static const struct i2c_algorithm xlr_i2c_algo = { - .master_xfer = xlr_i2c_xfer, - .functionality = xlr_func, -}; - -static const struct i2c_adapter_quirks xlr_i2c_quirks = { - .flags = I2C_AQ_NO_ZERO_LEN, -}; - -static const struct xlr_i2c_config xlr_i2c_config_default = { - .status_busy = XLR_I2C_BUS_BUSY, - .cfg_extra = 0, -}; - -static const struct xlr_i2c_config xlr_i2c_config_tangox = { - .flags = XLR_I2C_FLAG_IRQ, - .status_busy = 0, - .cfg_extra = 1 << 8, -}; - -static const struct of_device_id xlr_i2c_dt_ids[] = { - { - .compatible = "sigma,smp8642-i2c", - .data = &xlr_i2c_config_tangox, - }, - { } -}; -MODULE_DEVICE_TABLE(of, xlr_i2c_dt_ids); - -static int xlr_i2c_probe(struct platform_device *pdev) -{ - const struct of_device_id *match; - struct xlr_i2c_private *priv; - struct clk *clk; - unsigned long clk_rate; - unsigned long clk_div; - u32 busfreq; - int irq; - int ret; - - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - match = of_match_device(xlr_i2c_dt_ids, &pdev->dev); - if (match) - priv->cfg = match->data; - else - priv->cfg = &xlr_i2c_config_default; - - priv->iobase = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(priv->iobase)) - return PTR_ERR(priv->iobase); - - irq = platform_get_irq(pdev, 0); - - if (irq > 0 && (priv->cfg->flags & XLR_I2C_FLAG_IRQ)) { - priv->irq = irq; - - xlr_i2c_wreg(priv->iobase, XLR_I2C_INT_EN, 0); - xlr_i2c_wreg(priv->iobase, XLR_I2C_INT_STAT, 0xf); - - ret = devm_request_irq(&pdev->dev, priv->irq, xlr_i2c_irq, - IRQF_SHARED, dev_name(&pdev->dev), - priv); - if (ret) - return ret; - - init_waitqueue_head(&priv->wait); - } - - if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", - &busfreq)) - busfreq = I2C_MAX_STANDARD_MODE_FREQ; - - clk = devm_clk_get(&pdev->dev, NULL); - if (!IS_ERR(clk)) { - ret = clk_prepare_enable(clk); - if (ret) - return ret; - - clk_rate = clk_get_rate(clk); - clk_div = DIV_ROUND_UP(clk_rate, 2 * busfreq); - xlr_i2c_wreg(priv->iobase, XLR_I2C_CLKDIV, clk_div); - - clk_disable(clk); - priv->clk = clk; - } - - priv->adap.dev.parent = &pdev->dev; - priv->adap.dev.of_node = pdev->dev.of_node; - priv->adap.owner = THIS_MODULE; - priv->adap.algo_data = priv; - priv->adap.algo = &xlr_i2c_algo; - priv->adap.quirks = &xlr_i2c_quirks; - priv->adap.nr = pdev->id; - priv->adap.class = I2C_CLASS_HWMON; - snprintf(priv->adap.name, sizeof(priv->adap.name), "xlr-i2c"); - - i2c_set_adapdata(&priv->adap, priv); - ret = i2c_add_numbered_adapter(&priv->adap); - if (ret < 0) - goto err_unprepare_clk; - - platform_set_drvdata(pdev, priv); - dev_info(&priv->adap.dev, "Added I2C Bus.\n"); - return 0; - -err_unprepare_clk: - clk_unprepare(clk); - return ret; -} - -static int xlr_i2c_remove(struct platform_device *pdev) -{ - struct xlr_i2c_private *priv; - - priv = platform_get_drvdata(pdev); - i2c_del_adapter(&priv->adap); - clk_unprepare(priv->clk); - - return 0; -} - -static struct platform_driver xlr_i2c_driver = { - .probe = xlr_i2c_probe, - .remove = xlr_i2c_remove, - .driver = { - .name = "xlr-i2cbus", - .of_match_table = xlr_i2c_dt_ids, - }, -}; - -module_platform_driver(xlr_i2c_driver); - -MODULE_AUTHOR("Ganesan Ramalingam "); -MODULE_DESCRIPTION("XLR/XLS SoC I2C Controller driver"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:xlr-i2cbus");