diff options
Diffstat (limited to 'drivers/i2c')
100 files changed, 8457 insertions, 2086 deletions
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index fad22b0bb5b..65ef9664d5d 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -20,12 +20,11 @@   * ------------------------------------------------------------------------- */  /* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki -   <kmalkki@cc.hut.fi> and Jean Delvare <khali@linux-fr.org> */ +   <kmalkki@cc.hut.fi> and Jean Delvare <jdelvare@suse.de> */  #include <linux/kernel.h>  #include <linux/module.h>  #include <linux/delay.h> -#include <linux/init.h>  #include <linux/errno.h>  #include <linux/sched.h>  #include <linux/i2c.h> diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index f892a424009..8b10f88b13d 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -24,7 +24,6 @@  #include <linux/moduleparam.h>  #include <linux/delay.h>  #include <linux/jiffies.h> -#include <linux/init.h>  #include <linux/errno.h>  #include <linux/i2c.h>  #include <linux/i2c-algo-pca.h> diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index 5c2379522aa..34370090b75 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c @@ -30,7 +30,6 @@  #include <linux/kernel.h>  #include <linux/module.h>  #include <linux/delay.h> -#include <linux/init.h>  #include <linux/errno.h>  #include <linux/i2c.h>  #include <linux/i2c-algo-pcf.h> diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index cdcbd8368ed..9f7d5859cf6 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -109,6 +109,8 @@ config I2C_I801  	    Avoton (SOC)  	    Wellsburg (PCH)  	    Coleto Creek (PCH) +	    Wildcat Point-LP (PCH) +	    BayTrail (SOC)  	  This driver can also be built as a module.  If so, the module  	  will be called i2c-i801. @@ -151,6 +153,7 @@ config I2C_PIIX4  	    ATI SB700/SP5100  	    ATI SB800  	    AMD Hudson-2 +	    AMD ML  	    AMD CZ  	    Serverworks OSB4  	    Serverworks CSB5 @@ -345,6 +348,16 @@ config I2C_BCM2835  	  This support is also available as a module.  If so, the module  	  will be called i2c-bcm2835. +config I2C_BCM_KONA +	tristate "BCM Kona I2C adapter" +	depends on ARCH_BCM_MOBILE +	default y +	help +	  If you say yes to this option, support will be included for the +	  I2C interface on the Broadcom Kona family of processors. + +	  If you do not need KONA I2C inteface, say N. +  config I2C_BLACKFIN_TWI  	tristate "Blackfin TWI I2C support"  	depends on BLACKFIN @@ -363,6 +376,13 @@ config I2C_BLACKFIN_TWI_CLK_KHZ  	help  	  The unit of the TWI clock is kHz. +config I2C_CADENCE +	tristate "Cadence I2C Controller" +	depends on ARCH_ZYNQ +	help +	  Say yes here to select Cadence I2C Host Controller. This controller is +	  e.g. used by Xilinx Zynq. +  config I2C_CBUS_GPIO  	tristate "CBUS I2C driver"  	depends on GPIOLIB @@ -375,7 +395,7 @@ config I2C_CBUS_GPIO  config I2C_CPM  	tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)" -	depends on (CPM1 || CPM2) && OF_I2C +	depends on CPM1 || CPM2  	help  	  This supports the use of the I2C interface on Freescale  	  processors with CPM1 or CPM2. @@ -401,7 +421,6 @@ config I2C_DESIGNWARE_CORE  config I2C_DESIGNWARE_PLATFORM  	tristate "Synopsys DesignWare Platform" -	depends on HAVE_CLK  	select I2C_DESIGNWARE_CORE  	help  	  If you say yes to this option, support will be included for the @@ -421,9 +440,16 @@ config I2C_DESIGNWARE_PCI  	  This driver can also be built as a module.  If so, the module  	  will be called i2c-designware-pci. +config I2C_EFM32 +	tristate "EFM32 I2C controller" +	depends on ARCH_EFM32 || COMPILE_TEST +	help +	  This driver supports the i2c block found in Energy Micro's EFM32 +	  SoCs. +  config I2C_EG20T  	tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) I2C" -	depends on PCI +	depends on PCI && (X86_32 || COMPILE_TEST)  	help  	  This driver is for PCH(Platform controller Hub) I2C of EG20T which  	  is an IOH(Input/Output Hub) for x86 embedded processor. @@ -436,6 +462,13 @@ config I2C_EG20T  	  ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series.  	  ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH. +config I2C_EXYNOS5 +	tristate "Exynos5 high-speed I2C driver" +	depends on ARCH_EXYNOS5 && OF +	help +	  Say Y here to include support for high-speed I2C controller in the +	  Exynos5 based Samsung SoCs. +  config I2C_GPIO  	tristate "GPIO-based bitbanging I2C"  	depends on GPIOLIB @@ -509,7 +542,7 @@ config I2C_MPC  config I2C_MV64XXX  	tristate "Marvell mv64xxx I2C Controller" -	depends on (MV64X60 || PLAT_ORION || ARCH_SUNXI) +	depends on MV64X60 || PLAT_ORION || ARCH_SUNXI  	help  	  If you say yes to this option, support will be included for the  	  built-in I2C interface on the Marvell 64xxx line of host bridges. @@ -537,13 +570,6 @@ config I2C_NOMADIK  	  I2C interface from ST-Ericsson's Nomadik and Ux500 architectures,  	  as well as the STA2X11 PCIe I/O HUB. -config I2C_NUC900 -	tristate "NUC900 I2C Driver" -	depends on ARCH_W90X900 -	help -	  Say Y here to include support for I2C controller in the -	  Winbond/Nuvoton NUC900 based System-on-Chip devices. -  config I2C_OCORES  	tristate "OpenCores I2C Controller"  	help @@ -630,6 +656,36 @@ config I2C_PXA_SLAVE  	  is necessary for systems where the PXA may be a target on the  	  I2C bus. +config I2C_QUP +	tristate "Qualcomm QUP based I2C controller" +	depends on ARCH_QCOM +	help +	  If you say yes to this option, support will be included for the +	  built-in I2C interface on the Qualcomm SoCs. + +	  This driver can also be built as a module.  If so, the module +	  will be called i2c-qup. + +config I2C_RIIC +	tristate "Renesas RIIC adapter" +	depends on ARCH_SHMOBILE || COMPILE_TEST +	help +	  If you say yes to this option, support will be included for the +	  Renesas RIIC I2C interface. + +	  This driver can also be built as a module.  If so, the module +	  will be called i2c-riic. + +config I2C_RK3X +	tristate "Rockchip RK3xxx I2C adapter" +	depends on OF +	help +	  Say Y here to include support for the I2C adapter in Rockchip RK3xxx +	  SoCs. + +	  This driver can also be built as a module. If so, the module will +	  be called i2c-rk3x. +  config HAVE_S3C2410_I2C  	bool  	help @@ -665,7 +721,7 @@ config I2C_SH7760  config I2C_SH_MOBILE  	tristate "SuperH Mobile I2C Controller" -	depends on SUPERH || ARCH_SHMOBILE +	depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST  	help  	  If you say yes to this option, support will be included for the  	  built-in I2C interface on the Renesas SH-Mobile processor. @@ -695,6 +751,16 @@ config I2C_SIRF  	  This driver can also be built as a module.  If so, the module  	  will be called i2c-sirf. +config I2C_ST +	tristate "STMicroelectronics SSC I2C support" +	depends on ARCH_STI +	help +	  Enable this option to add support for STMicroelectronics SoCs +	  hardware SSC (Synchronous Serial Controller) as an I2C controller. + +	  This driver can also be built as module. If so, the module +	  will be called i2c-st. +  config I2C_STU300  	tristate "ST Microelectronics DDC I2C interface"  	depends on MACH_U300 @@ -708,6 +774,19 @@ config I2C_STU300  	  This driver can also be built as a module. If so, the module  	  will be called i2c-stu300. +config I2C_SUN6I_P2WI +	tristate "Allwinner sun6i internal P2WI controller" +	depends on RESET_CONTROLLER +	depends on MACH_SUN6I || COMPILE_TEST +	help +	  If you say yes to this option, support will be included for the +	  P2WI (Push/Pull 2 Wire Interface) controller embedded in some sunxi +	  SOCs. +	  The P2WI looks like an SMBus controller (which supports only byte +	  accesses), except that it only supports one slave device. +	  This interface is used to connect to specific PMIC devices (like the +	  AXP221). +  config I2C_TEGRA  	tristate "NVIDIA Tegra internal I2C controller"  	depends on ARCH_TEGRA @@ -768,7 +847,7 @@ config I2C_XLR  config I2C_RCAR  	tristate "Renesas R-Car I2C Controller" -	depends on ARCH_SHMOBILE && I2C +	depends on ARCH_SHMOBILE || COMPILE_TEST  	help  	  If you say yes to this option, support will be included for the  	  R-Car I2C controller. @@ -837,6 +916,16 @@ config I2C_PARPORT_LIGHT  	  This support is also available as a module.  If so, the module  	  will be called i2c-parport-light. +config I2C_ROBOTFUZZ_OSIF +	tristate "RobotFuzz Open Source InterFace USB adapter" +	depends on USB +	help +	  If you say yes to this option, support will be included for the +	  RobotFuzz Open Source InterFace USB to I2C interface. + +	  This driver can also be built as a module.  If so, the module +	  will be called i2c-osif. +  config I2C_TAOS_EVM  	tristate "TAOS evaluation module"  	depends on TTY @@ -888,7 +977,7 @@ config I2C_ACORN  config I2C_ELEKTOR  	tristate "Elektor ISA card" -	depends on ISA && HAS_IOPORT && BROKEN_ON_SMP +	depends on ISA && HAS_IOPORT_MAP && BROKEN_ON_SMP  	select I2C_ALGOPCF  	help  	  This supports the PCF8584 ISA bus I2C adapter.  Say Y if you own @@ -920,6 +1009,15 @@ config I2C_SIBYTE  	help  	  Supports the SiByte SOC on-chip I2C interfaces (2 channels). +config I2C_CROS_EC_TUNNEL +	tristate "ChromeOS EC tunnel I2C bus" +	depends on MFD_CROS_EC +	help +	  If you say yes here you get an I2C bus that will tunnel i2c commands +	  through to the other side of the ChromeOS EC to the i2c bus +	  connected there. This will work whatever the interface used to +	  talk to the EC (SPI, I2C or LPC). +  config SCx200_I2C  	tristate "NatSemi SCx200 I2C using GPIO pins (DEPRECATED)"  	depends on SCx200_GPIO diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index d00997f3eb3..dd9a7f8e873 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_I2C_AT91)		+= i2c-at91.o  obj-$(CONFIG_I2C_AU1550)	+= i2c-au1550.o  obj-$(CONFIG_I2C_BCM2835)	+= i2c-bcm2835.o  obj-$(CONFIG_I2C_BLACKFIN_TWI)	+= i2c-bfin-twi.o +obj-$(CONFIG_I2C_CADENCE)	+= i2c-cadence.o  obj-$(CONFIG_I2C_CBUS_GPIO)	+= i2c-cbus-gpio.o  obj-$(CONFIG_I2C_CPM)		+= i2c-cpm.o  obj-$(CONFIG_I2C_DAVINCI)	+= i2c-davinci.o @@ -41,7 +42,9 @@ obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM)	+= i2c-designware-platform.o  i2c-designware-platform-objs := i2c-designware-platdrv.o  obj-$(CONFIG_I2C_DESIGNWARE_PCI)	+= i2c-designware-pci.o  i2c-designware-pci-objs := i2c-designware-pcidrv.o +obj-$(CONFIG_I2C_EFM32)		+= i2c-efm32.o  obj-$(CONFIG_I2C_EG20T)		+= i2c-eg20t.o +obj-$(CONFIG_I2C_EXYNOS5)	+= i2c-exynos5.o  obj-$(CONFIG_I2C_GPIO)		+= i2c-gpio.o  obj-$(CONFIG_I2C_HIGHLANDER)	+= i2c-highlander.o  obj-$(CONFIG_I2C_IBM_IIC)	+= i2c-ibm_iic.o @@ -52,7 +55,6 @@ obj-$(CONFIG_I2C_MPC)		+= i2c-mpc.o  obj-$(CONFIG_I2C_MV64XXX)	+= i2c-mv64xxx.o  obj-$(CONFIG_I2C_MXS)		+= i2c-mxs.o  obj-$(CONFIG_I2C_NOMADIK)	+= i2c-nomadik.o -obj-$(CONFIG_I2C_NUC900)	+= i2c-nuc900.o  obj-$(CONFIG_I2C_OCORES)	+= i2c-ocores.o  obj-$(CONFIG_I2C_OMAP)		+= i2c-omap.o  obj-$(CONFIG_I2C_PASEMI)	+= i2c-pasemi.o @@ -62,13 +64,18 @@ obj-$(CONFIG_I2C_PNX)		+= i2c-pnx.o  obj-$(CONFIG_I2C_PUV3)		+= i2c-puv3.o  obj-$(CONFIG_I2C_PXA)		+= i2c-pxa.o  obj-$(CONFIG_I2C_PXA_PCI)	+= i2c-pxa-pci.o +obj-$(CONFIG_I2C_QUP)		+= i2c-qup.o +obj-$(CONFIG_I2C_RIIC)		+= i2c-riic.o +obj-$(CONFIG_I2C_RK3X)		+= i2c-rk3x.o  obj-$(CONFIG_I2C_S3C2410)	+= i2c-s3c2410.o  obj-$(CONFIG_I2C_S6000)		+= i2c-s6000.o  obj-$(CONFIG_I2C_SH7760)	+= i2c-sh7760.o  obj-$(CONFIG_I2C_SH_MOBILE)	+= i2c-sh_mobile.o  obj-$(CONFIG_I2C_SIMTEC)	+= i2c-simtec.o  obj-$(CONFIG_I2C_SIRF)		+= i2c-sirf.o +obj-$(CONFIG_I2C_ST)		+= i2c-st.o  obj-$(CONFIG_I2C_STU300)	+= i2c-stu300.o +obj-$(CONFIG_I2C_SUN6I_P2WI)	+= i2c-sun6i-p2wi.o  obj-$(CONFIG_I2C_TEGRA)		+= i2c-tegra.o  obj-$(CONFIG_I2C_VERSATILE)	+= i2c-versatile.o  obj-$(CONFIG_I2C_WMT)		+= i2c-wmt.o @@ -81,12 +88,15 @@ obj-$(CONFIG_I2C_RCAR)		+= i2c-rcar.o  obj-$(CONFIG_I2C_DIOLAN_U2C)	+= i2c-diolan-u2c.o  obj-$(CONFIG_I2C_PARPORT)	+= i2c-parport.o  obj-$(CONFIG_I2C_PARPORT_LIGHT)	+= i2c-parport-light.o +obj-$(CONFIG_I2C_ROBOTFUZZ_OSIF)	+= i2c-robotfuzz-osif.o  obj-$(CONFIG_I2C_TAOS_EVM)	+= i2c-taos-evm.o  obj-$(CONFIG_I2C_TINY_USB)	+= i2c-tiny-usb.o  obj-$(CONFIG_I2C_VIPERBOARD)	+= i2c-viperboard.o  # Other I2C/SMBus bus drivers  obj-$(CONFIG_I2C_ACORN)		+= i2c-acorn.o +obj-$(CONFIG_I2C_BCM_KONA)	+= i2c-bcm-kona.o +obj-$(CONFIG_I2C_CROS_EC_TUNNEL)	+= i2c-cros-ec-tunnel.o  obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o  obj-$(CONFIG_I2C_PCA_ISA)	+= i2c-pca-isa.o  obj-$(CONFIG_I2C_SIBYTE)	+= i2c-sibyte.o diff --git a/drivers/i2c/busses/i2c-acorn.c b/drivers/i2c/busses/i2c-acorn.c index ed9f48d566d..9d7be5af2bf 100644 --- a/drivers/i2c/busses/i2c-acorn.c +++ b/drivers/i2c/busses/i2c-acorn.c @@ -12,7 +12,7 @@   *  On Acorn machines, the following i2c devices are on the bus:   *	- PCF8583 real time clock & static RAM   */ -#include <linux/init.h> +#include <linux/module.h>  #include <linux/i2c.h>  #include <linux/i2c-algo-bit.h>  #include <linux/io.h> diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index 3f491815e2c..451e305f797 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -58,7 +58,6 @@  #include <linux/delay.h>  #include <linux/ioport.h>  #include <linux/i2c.h> -#include <linux/init.h>  #include <linux/acpi.h>  #include <linux/io.h> @@ -495,7 +494,7 @@ static struct i2c_adapter ali1535_adapter = {  	.algo		= &smbus_algorithm,  }; -static DEFINE_PCI_DEVICE_TABLE(ali1535_ids) = { +static const struct pci_device_id ali1535_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },  	{ },  }; diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 84ccd9496a5..15517d78d5f 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c @@ -20,7 +20,6 @@  #include <linux/delay.h>  #include <linux/i2c.h>  #include <linux/pci.h> -#include <linux/init.h>  #include <linux/acpi.h>  #define ALI1563_MAX_TIMEOUT	500 @@ -64,7 +63,7 @@  static struct pci_driver ali1563_pci_driver;  static unsigned short ali1563_smba; -static int ali1563_transaction(struct i2c_adapter * a, int size) +static int ali1563_transaction(struct i2c_adapter *a, int size)  {  	u32 data;  	int timeout; @@ -79,7 +78,7 @@ static int ali1563_transaction(struct i2c_adapter * a, int size)  	data = inb_p(SMB_HST_STS);  	if (data & HST_STS_BAD) {  		dev_err(&a->dev, "ali1563: Trying to reset busy device\n"); -		outb_p(data | HST_STS_BAD,SMB_HST_STS); +		outb_p(data | HST_STS_BAD, SMB_HST_STS);  		data = inb_p(SMB_HST_STS);  		if (data & HST_STS_BAD)  			return -EBUSY; @@ -103,10 +102,10 @@ static int ali1563_transaction(struct i2c_adapter * a, int size)  	if (!timeout) {  		dev_err(&a->dev, "Timeout - Trying to KILL transaction!\n");  		/* Issue 'kill' to host controller */ -		outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2); +		outb_p(HST_CNTL2_KILL, SMB_HST_CNTL2);  		data = inb_p(SMB_HST_STS);  		status = -ETIMEDOUT; - 	} +	}  	/* device error - no response, ignore the autodetection case */  	if (data & HST_STS_DEVERR) { @@ -118,18 +117,18 @@ static int ali1563_transaction(struct i2c_adapter * a, int size)  	if (data & HST_STS_BUSERR) {  		dev_err(&a->dev, "Bus collision!\n");  		/* Issue timeout, hoping it helps */ -		outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1); +		outb_p(HST_CNTL1_TIMEOUT, SMB_HST_CNTL1);  	}  	if (data & HST_STS_FAIL) {  		dev_err(&a->dev, "Cleaning fail after KILL!\n"); -		outb_p(0x0,SMB_HST_CNTL2); +		outb_p(0x0, SMB_HST_CNTL2);  	}  	return status;  } -static int ali1563_block_start(struct i2c_adapter * a) +static int ali1563_block_start(struct i2c_adapter *a)  {  	u32 data;  	int timeout; @@ -143,8 +142,8 @@ static int ali1563_block_start(struct i2c_adapter * a)  	data = inb_p(SMB_HST_STS);  	if (data & HST_STS_BAD) { -		dev_warn(&a->dev,"ali1563: Trying to reset busy device\n"); -		outb_p(data | HST_STS_BAD,SMB_HST_STS); +		dev_warn(&a->dev, "ali1563: Trying to reset busy device\n"); +		outb_p(data | HST_STS_BAD, SMB_HST_STS);  		data = inb_p(SMB_HST_STS);  		if (data & HST_STS_BAD)  			return -EBUSY; @@ -185,13 +184,14 @@ static int ali1563_block_start(struct i2c_adapter * a)  	return status;  } -static int ali1563_block(struct i2c_adapter * a, union i2c_smbus_data * data, u8 rw) +static int ali1563_block(struct i2c_adapter *a, +			 union i2c_smbus_data *data, u8 rw)  {  	int i, len;  	int error = 0;  	/* Do we need this? */ -	outb_p(HST_CNTL1_LAST,SMB_HST_CNTL1); +	outb_p(HST_CNTL1_LAST, SMB_HST_CNTL1);  	if (rw == I2C_SMBUS_WRITE) {  		len = data->block[0]; @@ -199,8 +199,8 @@ static int ali1563_block(struct i2c_adapter * a, union i2c_smbus_data * data, u8  			len = 1;  		else if (len > 32)  			len = 32; -		outb_p(len,SMB_HST_DAT0); -		outb_p(data->block[1],SMB_BLK_DAT); +		outb_p(len, SMB_HST_DAT0); +		outb_p(data->block[1], SMB_BLK_DAT);  	} else  		len = 32; @@ -209,10 +209,12 @@ static int ali1563_block(struct i2c_adapter * a, union i2c_smbus_data * data, u8  	for (i = 0; i < len; i++) {  		if (rw == I2C_SMBUS_WRITE) {  			outb_p(data->block[i + 1], SMB_BLK_DAT); -			if ((error = ali1563_block_start(a))) +			error = ali1563_block_start(a); +			if (error)  				break;  		} else { -			if ((error = ali1563_block_start(a))) +			error = ali1563_block_start(a); +			if (error)  				break;  			if (i == 0) {  				len = inb_p(SMB_HST_DAT0); @@ -225,25 +227,26 @@ static int ali1563_block(struct i2c_adapter * a, union i2c_smbus_data * data, u8  		}  	}  	/* Do we need this? */ -	outb_p(HST_CNTL1_LAST,SMB_HST_CNTL1); +	outb_p(HST_CNTL1_LAST, SMB_HST_CNTL1);  	return error;  } -static s32 ali1563_access(struct i2c_adapter * a, u16 addr, +static s32 ali1563_access(struct i2c_adapter *a, u16 addr,  			  unsigned short flags, char rw, u8 cmd, -			  int size, union i2c_smbus_data * data) +			  int size, union i2c_smbus_data *data)  {  	int error = 0;  	int timeout;  	u32 reg;  	for (timeout = ALI1563_MAX_TIMEOUT; timeout; timeout--) { -		if (!(reg = inb_p(SMB_HST_STS) & HST_STS_BUSY)) +		reg = inb_p(SMB_HST_STS); +		if (!(reg & HST_STS_BUSY))  			break;  	}  	if (!timeout) -		dev_warn(&a->dev,"SMBus not idle. HST_STS = %02x\n",reg); -	outb_p(0xff,SMB_HST_STS); +		dev_warn(&a->dev, "SMBus not idle. HST_STS = %02x\n", reg); +	outb_p(0xff, SMB_HST_STS);  	/* Map the size to what the chip understands */  	switch (size) { @@ -269,13 +272,14 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr,  	}  	outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); -	outb_p((inb_p(SMB_HST_CNTL2) & ~HST_CNTL2_SIZEMASK) | (size << 3), SMB_HST_CNTL2); +	outb_p((inb_p(SMB_HST_CNTL2) & ~HST_CNTL2_SIZEMASK) | +	       (size << 3), SMB_HST_CNTL2);  	/* Write the command register */ -	switch(size) { +	switch (size) {  	case HST_CNTL2_BYTE: -		if (rw== I2C_SMBUS_WRITE) +		if (rw == I2C_SMBUS_WRITE)  			/* Beware it uses DAT0 register and not CMD! */  			outb_p(cmd, SMB_HST_DAT0);  		break; @@ -293,11 +297,12 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr,  		break;  	case HST_CNTL2_BLOCK:  		outb_p(cmd, SMB_HST_CMD); -		error = ali1563_block(a,data,rw); +		error = ali1563_block(a, data, rw);  		goto Done;  	} -	if ((error = ali1563_transaction(a, size))) +	error = ali1563_transaction(a, size); +	if (error)  		goto Done;  	if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK)) @@ -318,7 +323,7 @@ Done:  	return error;  } -static u32 ali1563_func(struct i2c_adapter * a) +static u32 ali1563_func(struct i2c_adapter *a)  {  	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |  	    I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | @@ -330,13 +335,13 @@ static int ali1563_setup(struct pci_dev *dev)  {  	u16 ctrl; -	pci_read_config_word(dev,ALI1563_SMBBA,&ctrl); +	pci_read_config_word(dev, ALI1563_SMBBA, &ctrl);  	/* SMB I/O Base in high 12 bits and must be aligned with the  	 * size of the I/O space. */  	ali1563_smba = ctrl & ~(ALI1563_SMB_IOSIZE - 1);  	if (!ali1563_smba) { -		dev_warn(&dev->dev,"ali1563_smba Uninitialized\n"); +		dev_warn(&dev->dev, "ali1563_smba Uninitialized\n");  		goto Err;  	} @@ -351,8 +356,8 @@ static int ali1563_setup(struct pci_dev *dev)  				      ctrl | ALI1563_SMB_IOEN);  		pci_read_config_word(dev, ALI1563_SMBBA, &ctrl);  		if (!(ctrl & ALI1563_SMB_IOEN)) { -			dev_err(&dev->dev, "I/O space still not enabled, " -				"giving up\n"); +			dev_err(&dev->dev, +				"I/O space still not enabled, giving up\n");  			goto Err;  		}  	} @@ -376,7 +381,7 @@ Err:  static void ali1563_shutdown(struct pci_dev *dev)  { -	release_region(ali1563_smba,ALI1563_SMB_IOSIZE); +	release_region(ali1563_smba, ALI1563_SMB_IOSIZE);  }  static const struct i2c_algorithm ali1563_algorithm = { @@ -395,12 +400,14 @@ static int ali1563_probe(struct pci_dev *dev,  {  	int error; -	if ((error = ali1563_setup(dev))) +	error = ali1563_setup(dev); +	if (error)  		goto exit;  	ali1563_adapter.dev.parent = &dev->dev;  	snprintf(ali1563_adapter.name, sizeof(ali1563_adapter.name),  		 "SMBus ALi 1563 Adapter @ %04x", ali1563_smba); -	if ((error = i2c_add_adapter(&ali1563_adapter))) +	error = i2c_add_adapter(&ali1563_adapter); +	if (error)  		goto exit_shutdown;  	return 0; @@ -417,17 +424,17 @@ static void ali1563_remove(struct pci_dev *dev)  	ali1563_shutdown(dev);  } -static DEFINE_PCI_DEVICE_TABLE(ali1563_id_table) = { +static const struct pci_device_id ali1563_id_table[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1563) },  	{},  }; -MODULE_DEVICE_TABLE (pci, ali1563_id_table); +MODULE_DEVICE_TABLE(pci, ali1563_id_table);  static struct pci_driver ali1563_pci_driver = { - 	.name		= "ali1563_smbus", +	.name		= "ali1563_smbus",  	.id_table	= ali1563_id_table, - 	.probe		= ali1563_probe, +	.probe		= ali1563_probe,  	.remove		= ali1563_remove,  }; diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c index 26bcc6127ce..2fa21ce9682 100644 --- a/drivers/i2c/busses/i2c-ali15x3.c +++ b/drivers/i2c/busses/i2c-ali15x3.c @@ -65,7 +65,6 @@  #include <linux/ioport.h>  #include <linux/delay.h>  #include <linux/i2c.h> -#include <linux/init.h>  #include <linux/acpi.h>  #include <linux/io.h> @@ -477,7 +476,7 @@ static struct i2c_adapter ali15x3_adapter = {  	.algo		= &smbus_algorithm,  }; -static DEFINE_PCI_DEVICE_TABLE(ali15x3_ids) = { +static const struct pci_device_id ali15x3_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },  	{ 0, }  }; diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c index 07f01ac853f..41fc6837fb8 100644 --- a/drivers/i2c/busses/i2c-amd756-s4882.c +++ b/drivers/i2c/busses/i2c-amd756-s4882.c @@ -1,7 +1,7 @@  /*   * i2c-amd756-s4882.c - i2c-amd756 extras for the Tyan S4882 motherboard   * - * Copyright (C) 2004, 2008 Jean Delvare <khali@linux-fr.org> + * Copyright (C) 2004, 2008 Jean Delvare <jdelvare@suse.de>   *   * 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 @@ -250,7 +250,7 @@ static void __exit amd756_s4882_exit(void)  		       "Physical bus restoration failed\n");  } -MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); +MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");  MODULE_DESCRIPTION("S4882 SMBus multiplexing");  MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index e13e2aa2d05..a16f7289135 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c @@ -41,7 +41,6 @@  #include <linux/stddef.h>  #include <linux/ioport.h>  #include <linux/i2c.h> -#include <linux/init.h>  #include <linux/acpi.h>  #include <linux/io.h> @@ -308,7 +307,7 @@ static const char* chipname[] = {  	"nVidia nForce", "AMD8111",  }; -static DEFINE_PCI_DEVICE_TABLE(amd756_ids) = { +static const struct pci_device_id amd756_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B),  	  .driver_data = AMD756 },  	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413), diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index a44e6e77c5a..95a80a8f81b 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -13,7 +13,6 @@  #include <linux/kernel.h>  #include <linux/stddef.h>  #include <linux/ioport.h> -#include <linux/init.h>  #include <linux/i2c.h>  #include <linux/delay.h>  #include <linux/acpi.h> @@ -415,7 +414,7 @@ static const struct i2c_algorithm smbus_algorithm = {  }; -static DEFINE_PCI_DEVICE_TABLE(amd8111_ids) = { +static const struct pci_device_id amd8111_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS2) },  	{ 0, }  }; diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index fd059308aff..e95f9ba9679 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -32,7 +32,7 @@  #include <linux/slab.h>  #include <linux/platform_data/dma-atmel.h> -#define TWI_CLK_HZ		100000			/* max 400 Kbits/s */ +#define DEFAULT_TWI_CLK_HZ		100000		/* max 400 Kbits/s */  #define AT91_I2C_TIMEOUT	msecs_to_jiffies(100)	/* transfer timeout */  #define AT91_I2C_DMA_THRESHOLD	8			/* enable DMA if transfer size is bigger than this threshold */ @@ -371,7 +371,7 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)  	dev_dbg(dev->dev, "transfer: %s %d bytes.\n",  		(dev->msg->flags & I2C_M_RD) ? "read" : "write", dev->buf_len); -	INIT_COMPLETION(dev->cmd_complete); +	reinit_completion(&dev->cmd_complete);  	dev->transfer_status = 0;  	if (!dev->buf_len) { @@ -589,6 +589,9 @@ static const struct of_device_id atmel_twi_dt_ids[] = {  		.compatible = "atmel,at91sam9260-i2c",  		.data = &at91sam9260_config,  	} , { +		.compatible = "atmel,at91sam9261-i2c", +		.data = &at91sam9261_config, +	} , {  		.compatible = "atmel,at91sam9g20-i2c",  		.data = &at91sam9g20_config,  	} , { @@ -708,6 +711,7 @@ static int at91_twi_probe(struct platform_device *pdev)  	struct resource *mem;  	int rc;  	u32 phy_addr; +	u32 bus_clk_rate;  	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);  	if (!dev) @@ -753,13 +757,18 @@ static int at91_twi_probe(struct platform_device *pdev)  			dev->use_dma = true;  	} -	at91_calc_twi_clock(dev, TWI_CLK_HZ); +	rc = of_property_read_u32(dev->dev->of_node, "clock-frequency", +			&bus_clk_rate); +	if (rc) +		bus_clk_rate = DEFAULT_TWI_CLK_HZ; + +	at91_calc_twi_clock(dev, bus_clk_rate);  	at91_init_twi_bus(dev);  	snprintf(dev->adapter.name, sizeof(dev->adapter.name), "AT91");  	i2c_set_adapdata(&dev->adapter, dev);  	dev->adapter.owner = THIS_MODULE; -	dev->adapter.class = I2C_CLASS_HWMON; +	dev->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED;  	dev->adapter.algo = &at91_twi_algorithm;  	dev->adapter.dev.parent = dev->dev;  	dev->adapter.nr = pdev->id; diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c index b5b89239d62..8762458ca7d 100644 --- a/drivers/i2c/busses/i2c-au1550.c +++ b/drivers/i2c/busses/i2c-au1550.c @@ -31,7 +31,6 @@  #include <linux/kernel.h>  #include <linux/module.h>  #include <linux/platform_device.h> -#include <linux/init.h>  #include <linux/errno.h>  #include <linux/i2c.h>  #include <linux/slab.h> diff --git a/drivers/i2c/busses/i2c-bcm-kona.c b/drivers/i2c/busses/i2c-bcm-kona.c new file mode 100644 index 00000000000..18a74a6751a --- /dev/null +++ b/drivers/i2c/busses/i2c-bcm-kona.c @@ -0,0 +1,908 @@ +/* + * Copyright (C) 2013 Broadcom Corporation + * + * 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 version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/slab.h> + +/* Hardware register offsets and field defintions */ +#define CS_OFFSET				0x00000020 +#define CS_ACK_SHIFT				3 +#define CS_ACK_MASK				0x00000008 +#define CS_ACK_CMD_GEN_START			0x00000000 +#define CS_ACK_CMD_GEN_RESTART			0x00000001 +#define CS_CMD_SHIFT				1 +#define CS_CMD_CMD_NO_ACTION			0x00000000 +#define CS_CMD_CMD_START_RESTART		0x00000001 +#define CS_CMD_CMD_STOP				0x00000002 +#define CS_EN_SHIFT				0 +#define CS_EN_CMD_ENABLE_BSC			0x00000001 + +#define TIM_OFFSET				0x00000024 +#define TIM_PRESCALE_SHIFT			6 +#define TIM_P_SHIFT				3 +#define TIM_NO_DIV_SHIFT			2 +#define TIM_DIV_SHIFT				0 + +#define DAT_OFFSET				0x00000028 + +#define TOUT_OFFSET				0x0000002c + +#define TXFCR_OFFSET				0x0000003c +#define TXFCR_FIFO_FLUSH_MASK			0x00000080 +#define TXFCR_FIFO_EN_MASK			0x00000040 + +#define IER_OFFSET				0x00000044 +#define IER_READ_COMPLETE_INT_MASK		0x00000010 +#define IER_I2C_INT_EN_MASK			0x00000008 +#define IER_FIFO_INT_EN_MASK			0x00000002 +#define IER_NOACK_EN_MASK			0x00000001 + +#define ISR_OFFSET				0x00000048 +#define ISR_RESERVED_MASK			0xffffff60 +#define ISR_CMDBUSY_MASK			0x00000080 +#define ISR_READ_COMPLETE_MASK			0x00000010 +#define ISR_SES_DONE_MASK			0x00000008 +#define ISR_ERR_MASK				0x00000004 +#define ISR_TXFIFOEMPTY_MASK			0x00000002 +#define ISR_NOACK_MASK				0x00000001 + +#define CLKEN_OFFSET				0x0000004C +#define CLKEN_AUTOSENSE_OFF_MASK		0x00000080 +#define CLKEN_M_SHIFT				4 +#define CLKEN_N_SHIFT				1 +#define CLKEN_CLKEN_MASK			0x00000001 + +#define FIFO_STATUS_OFFSET			0x00000054 +#define FIFO_STATUS_RXFIFO_EMPTY_MASK		0x00000004 +#define FIFO_STATUS_TXFIFO_EMPTY_MASK		0x00000010 + +#define HSTIM_OFFSET				0x00000058 +#define HSTIM_HS_MODE_MASK			0x00008000 +#define HSTIM_HS_HOLD_SHIFT			10 +#define HSTIM_HS_HIGH_PHASE_SHIFT		5 +#define HSTIM_HS_SETUP_SHIFT			0 + +#define PADCTL_OFFSET				0x0000005c +#define PADCTL_PAD_OUT_EN_MASK			0x00000004 + +#define RXFCR_OFFSET				0x00000068 +#define RXFCR_NACK_EN_SHIFT			7 +#define RXFCR_READ_COUNT_SHIFT			0 +#define RXFIFORDOUT_OFFSET			0x0000006c + +/* Locally used constants */ +#define MAX_RX_FIFO_SIZE		64U /* bytes */ +#define MAX_TX_FIFO_SIZE		64U /* bytes */ + +#define STD_EXT_CLK_FREQ		13000000UL +#define HS_EXT_CLK_FREQ			104000000UL + +#define MASTERCODE			0x08 /* Mastercodes are 0000_1xxxb */ + +#define I2C_TIMEOUT			100 /* msecs */ + +/* Operations that can be commanded to the controller */ +enum bcm_kona_cmd_t { +	BCM_CMD_NOACTION = 0, +	BCM_CMD_START, +	BCM_CMD_RESTART, +	BCM_CMD_STOP, +}; + +enum bus_speed_index { +	BCM_SPD_100K = 0, +	BCM_SPD_400K, +	BCM_SPD_1MHZ, +}; + +enum hs_bus_speed_index { +	BCM_SPD_3P4MHZ = 0, +}; + +/* Internal divider settings for standard mode, fast mode and fast mode plus */ +struct bus_speed_cfg { +	uint8_t time_m;		/* Number of cycles for setup time */ +	uint8_t time_n;		/* Number of cycles for hold time */ +	uint8_t prescale;	/* Prescale divider */ +	uint8_t time_p;		/* Timing coefficient */ +	uint8_t no_div;		/* Disable clock divider */ +	uint8_t time_div;	/* Post-prescale divider */ +}; + +/* Internal divider settings for high-speed mode */ +struct hs_bus_speed_cfg { +	uint8_t hs_hold;	/* Number of clock cycles SCL stays low until +				   the end of bit period */ +	uint8_t hs_high_phase;	/* Number of clock cycles SCL stays high +				   before it falls */ +	uint8_t hs_setup;	/* Number of clock cycles SCL stays low +				   before it rises  */ +	uint8_t prescale;	/* Prescale divider */ +	uint8_t time_p;		/* Timing coefficient */ +	uint8_t no_div;		/* Disable clock divider */ +	uint8_t time_div;	/* Post-prescale divider */ +}; + +static const struct bus_speed_cfg std_cfg_table[] = { +	[BCM_SPD_100K] = {0x01, 0x01, 0x03, 0x06, 0x00, 0x02}, +	[BCM_SPD_400K] = {0x05, 0x01, 0x03, 0x05, 0x01, 0x02}, +	[BCM_SPD_1MHZ] = {0x01, 0x01, 0x03, 0x01, 0x01, 0x03}, +}; + +static const struct hs_bus_speed_cfg hs_cfg_table[] = { +	[BCM_SPD_3P4MHZ] = {0x01, 0x08, 0x14, 0x00, 0x06, 0x01, 0x00}, +}; + +struct bcm_kona_i2c_dev { +	struct device *device; + +	void __iomem *base; +	int irq; +	struct clk *external_clk; + +	struct i2c_adapter adapter; + +	struct completion done; + +	const struct bus_speed_cfg *std_cfg; +	const struct hs_bus_speed_cfg *hs_cfg; +}; + +static void bcm_kona_i2c_send_cmd_to_ctrl(struct bcm_kona_i2c_dev *dev, +					  enum bcm_kona_cmd_t cmd) +{ +	dev_dbg(dev->device, "%s, %d\n", __func__, cmd); + +	switch (cmd) { +	case BCM_CMD_NOACTION: +		writel((CS_CMD_CMD_NO_ACTION << CS_CMD_SHIFT) | +		       (CS_EN_CMD_ENABLE_BSC << CS_EN_SHIFT), +		       dev->base + CS_OFFSET); +		break; + +	case BCM_CMD_START: +		writel((CS_ACK_CMD_GEN_START << CS_ACK_SHIFT) | +		       (CS_CMD_CMD_START_RESTART << CS_CMD_SHIFT) | +		       (CS_EN_CMD_ENABLE_BSC << CS_EN_SHIFT), +		       dev->base + CS_OFFSET); +		break; + +	case BCM_CMD_RESTART: +		writel((CS_ACK_CMD_GEN_RESTART << CS_ACK_SHIFT) | +		       (CS_CMD_CMD_START_RESTART << CS_CMD_SHIFT) | +		       (CS_EN_CMD_ENABLE_BSC << CS_EN_SHIFT), +		       dev->base + CS_OFFSET); +		break; + +	case BCM_CMD_STOP: +		writel((CS_CMD_CMD_STOP << CS_CMD_SHIFT) | +		       (CS_EN_CMD_ENABLE_BSC << CS_EN_SHIFT), +		       dev->base + CS_OFFSET); +		break; + +	default: +		dev_err(dev->device, "Unknown command %d\n", cmd); +	} +} + +static void bcm_kona_i2c_enable_clock(struct bcm_kona_i2c_dev *dev) +{ +	writel(readl(dev->base + CLKEN_OFFSET) | CLKEN_CLKEN_MASK, +	       dev->base + CLKEN_OFFSET); +} + +static void bcm_kona_i2c_disable_clock(struct bcm_kona_i2c_dev *dev) +{ +	writel(readl(dev->base + CLKEN_OFFSET) & ~CLKEN_CLKEN_MASK, +	       dev->base + CLKEN_OFFSET); +} + +static irqreturn_t bcm_kona_i2c_isr(int irq, void *devid) +{ +	struct bcm_kona_i2c_dev *dev = devid; +	uint32_t status = readl(dev->base + ISR_OFFSET); + +	if ((status & ~ISR_RESERVED_MASK) == 0) +		return IRQ_NONE; + +	/* Must flush the TX FIFO when NAK detected */ +	if (status & ISR_NOACK_MASK) +		writel(TXFCR_FIFO_FLUSH_MASK | TXFCR_FIFO_EN_MASK, +		       dev->base + TXFCR_OFFSET); + +	writel(status & ~ISR_RESERVED_MASK, dev->base + ISR_OFFSET); +	complete_all(&dev->done); + +	return IRQ_HANDLED; +} + +/* Wait for ISR_CMDBUSY_MASK to go low before writing to CS, DAT, or RCD */ +static int bcm_kona_i2c_wait_if_busy(struct bcm_kona_i2c_dev *dev) +{ +	unsigned long timeout = jiffies + msecs_to_jiffies(I2C_TIMEOUT); + +	while (readl(dev->base + ISR_OFFSET) & ISR_CMDBUSY_MASK) +		if (time_after(jiffies, timeout)) { +			dev_err(dev->device, "CMDBUSY timeout\n"); +			return -ETIMEDOUT; +		} + +	return 0; +} + +/* Send command to I2C bus */ +static int bcm_kona_send_i2c_cmd(struct bcm_kona_i2c_dev *dev, +				 enum bcm_kona_cmd_t cmd) +{ +	int rc; +	unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT); + +	/* Make sure the hardware is ready */ +	rc = bcm_kona_i2c_wait_if_busy(dev); +	if (rc < 0) +		return rc; + +	/* Unmask the session done interrupt */ +	writel(IER_I2C_INT_EN_MASK, dev->base + IER_OFFSET); + +	/* Mark as incomplete before sending the command */ +	reinit_completion(&dev->done); + +	/* Send the command */ +	bcm_kona_i2c_send_cmd_to_ctrl(dev, cmd); + +	/* Wait for transaction to finish or timeout */ +	time_left = wait_for_completion_timeout(&dev->done, time_left); + +	/* Mask all interrupts */ +	writel(0, dev->base + IER_OFFSET); + +	if (!time_left) { +		dev_err(dev->device, "controller timed out\n"); +		rc = -ETIMEDOUT; +	} + +	/* Clear command */ +	bcm_kona_i2c_send_cmd_to_ctrl(dev, BCM_CMD_NOACTION); + +	return rc; +} + +/* Read a single RX FIFO worth of data from the i2c bus */ +static int bcm_kona_i2c_read_fifo_single(struct bcm_kona_i2c_dev *dev, +					 uint8_t *buf, unsigned int len, +					 unsigned int last_byte_nak) +{ +	unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT); + +	/* Mark as incomplete before starting the RX FIFO */ +	reinit_completion(&dev->done); + +	/* Unmask the read complete interrupt */ +	writel(IER_READ_COMPLETE_INT_MASK, dev->base + IER_OFFSET); + +	/* Start the RX FIFO */ +	writel((last_byte_nak << RXFCR_NACK_EN_SHIFT) | +	       (len << RXFCR_READ_COUNT_SHIFT), +		dev->base + RXFCR_OFFSET); + +	/* Wait for FIFO read to complete */ +	time_left = wait_for_completion_timeout(&dev->done, time_left); + +	/* Mask all interrupts */ +	writel(0, dev->base + IER_OFFSET); + +	if (!time_left) { +		dev_err(dev->device, "RX FIFO time out\n"); +		return -EREMOTEIO; +	} + +	/* Read data from FIFO */ +	for (; len > 0; len--, buf++) +		*buf = readl(dev->base + RXFIFORDOUT_OFFSET); + +	return 0; +} + +/* Read any amount of data using the RX FIFO from the i2c bus */ +static int bcm_kona_i2c_read_fifo(struct bcm_kona_i2c_dev *dev, +				  struct i2c_msg *msg) +{ +	unsigned int bytes_to_read = MAX_RX_FIFO_SIZE; +	unsigned int last_byte_nak = 0; +	unsigned int bytes_read = 0; +	int rc; + +	uint8_t *tmp_buf = msg->buf; + +	while (bytes_read < msg->len) { +		if (msg->len - bytes_read <= MAX_RX_FIFO_SIZE) { +			last_byte_nak = 1; /* NAK last byte of transfer */ +			bytes_to_read = msg->len - bytes_read; +		} + +		rc = bcm_kona_i2c_read_fifo_single(dev, tmp_buf, bytes_to_read, +						   last_byte_nak); +		if (rc < 0) +			return -EREMOTEIO; + +		bytes_read += bytes_to_read; +		tmp_buf += bytes_to_read; +	} + +	return 0; +} + +/* Write a single byte of data to the i2c bus */ +static int bcm_kona_i2c_write_byte(struct bcm_kona_i2c_dev *dev, uint8_t data, +				   unsigned int nak_expected) +{ +	int rc; +	unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT); +	unsigned int nak_received; + +	/* Make sure the hardware is ready */ +	rc = bcm_kona_i2c_wait_if_busy(dev); +	if (rc < 0) +		return rc; + +	/* Clear pending session done interrupt */ +	writel(ISR_SES_DONE_MASK, dev->base + ISR_OFFSET); + +	/* Unmask the session done interrupt */ +	writel(IER_I2C_INT_EN_MASK, dev->base + IER_OFFSET); + +	/* Mark as incomplete before sending the data */ +	reinit_completion(&dev->done); + +	/* Send one byte of data */ +	writel(data, dev->base + DAT_OFFSET); + +	/* Wait for byte to be written */ +	time_left = wait_for_completion_timeout(&dev->done, time_left); + +	/* Mask all interrupts */ +	writel(0, dev->base + IER_OFFSET); + +	if (!time_left) { +		dev_dbg(dev->device, "controller timed out\n"); +		return -ETIMEDOUT; +	} + +	nak_received = readl(dev->base + CS_OFFSET) & CS_ACK_MASK ? 1 : 0; + +	if (nak_received ^ nak_expected) { +		dev_dbg(dev->device, "unexpected NAK/ACK\n"); +		return -EREMOTEIO; +	} + +	return 0; +} + +/* Write a single TX FIFO worth of data to the i2c bus */ +static int bcm_kona_i2c_write_fifo_single(struct bcm_kona_i2c_dev *dev, +					  uint8_t *buf, unsigned int len) +{ +	int k; +	unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT); +	unsigned int fifo_status; + +	/* Mark as incomplete before sending data to the TX FIFO */ +	reinit_completion(&dev->done); + +	/* Unmask the fifo empty and nak interrupt */ +	writel(IER_FIFO_INT_EN_MASK | IER_NOACK_EN_MASK, +	       dev->base + IER_OFFSET); + +	/* Disable IRQ to load a FIFO worth of data without interruption */ +	disable_irq(dev->irq); + +	/* Write data into FIFO */ +	for (k = 0; k < len; k++) +		writel(buf[k], (dev->base + DAT_OFFSET)); + +	/* Enable IRQ now that data has been loaded */ +	enable_irq(dev->irq); + +	/* Wait for FIFO to empty */ +	do { +		time_left = wait_for_completion_timeout(&dev->done, time_left); +		fifo_status = readl(dev->base + FIFO_STATUS_OFFSET); +	} while (time_left && !(fifo_status & FIFO_STATUS_TXFIFO_EMPTY_MASK)); + +	/* Mask all interrupts */ +	writel(0, dev->base + IER_OFFSET); + +	/* Check if there was a NAK */ +	if (readl(dev->base + CS_OFFSET) & CS_ACK_MASK) { +		dev_err(dev->device, "unexpected NAK\n"); +		return -EREMOTEIO; +	} + +	/* Check if a timeout occured */ +	if (!time_left) { +		dev_err(dev->device, "completion timed out\n"); +		return -EREMOTEIO; +	} + +	return 0; +} + + +/* Write any amount of data using TX FIFO to the i2c bus */ +static int bcm_kona_i2c_write_fifo(struct bcm_kona_i2c_dev *dev, +				   struct i2c_msg *msg) +{ +	unsigned int bytes_to_write = MAX_TX_FIFO_SIZE; +	unsigned int bytes_written = 0; +	int rc; + +	uint8_t *tmp_buf = msg->buf; + +	while (bytes_written < msg->len) { +		if (msg->len - bytes_written <= MAX_TX_FIFO_SIZE) +			bytes_to_write = msg->len - bytes_written; + +		rc = bcm_kona_i2c_write_fifo_single(dev, tmp_buf, +						    bytes_to_write); +		if (rc < 0) +			return -EREMOTEIO; + +		bytes_written += bytes_to_write; +		tmp_buf += bytes_to_write; +	} + +	return 0; +} + +/* Send i2c address */ +static int bcm_kona_i2c_do_addr(struct bcm_kona_i2c_dev *dev, +				     struct i2c_msg *msg) +{ +	unsigned char addr; + +	if (msg->flags & I2C_M_TEN) { +		/* First byte is 11110XX0 where XX is upper 2 bits */ +		addr = 0xF0 | ((msg->addr & 0x300) >> 7); +		if (bcm_kona_i2c_write_byte(dev, addr, 0) < 0) +			return -EREMOTEIO; + +		/* Second byte is the remaining 8 bits */ +		addr = msg->addr & 0xFF; +		if (bcm_kona_i2c_write_byte(dev, addr, 0) < 0) +			return -EREMOTEIO; + +		if (msg->flags & I2C_M_RD) { +			/* For read, send restart command */ +			if (bcm_kona_send_i2c_cmd(dev, BCM_CMD_RESTART) < 0) +				return -EREMOTEIO; + +			/* Then re-send the first byte with the read bit set */ +			addr = 0xF0 | ((msg->addr & 0x300) >> 7) | 0x01; +			if (bcm_kona_i2c_write_byte(dev, addr, 0) < 0) +				return -EREMOTEIO; +		} +	} else { +		addr = msg->addr << 1; + +		if (msg->flags & I2C_M_RD) +			addr |= 1; + +		if (bcm_kona_i2c_write_byte(dev, addr, 0) < 0) +			return -EREMOTEIO; +	} + +	return 0; +} + +static void bcm_kona_i2c_enable_autosense(struct bcm_kona_i2c_dev *dev) +{ +	writel(readl(dev->base + CLKEN_OFFSET) & ~CLKEN_AUTOSENSE_OFF_MASK, +	       dev->base + CLKEN_OFFSET); +} + +static void bcm_kona_i2c_config_timing(struct bcm_kona_i2c_dev *dev) +{ +	writel(readl(dev->base + HSTIM_OFFSET) & ~HSTIM_HS_MODE_MASK, +	       dev->base + HSTIM_OFFSET); + +	writel((dev->std_cfg->prescale << TIM_PRESCALE_SHIFT) | +	       (dev->std_cfg->time_p << TIM_P_SHIFT) | +	       (dev->std_cfg->no_div << TIM_NO_DIV_SHIFT) | +	       (dev->std_cfg->time_div	<< TIM_DIV_SHIFT), +	       dev->base + TIM_OFFSET); + +	writel((dev->std_cfg->time_m << CLKEN_M_SHIFT) | +	       (dev->std_cfg->time_n << CLKEN_N_SHIFT) | +	       CLKEN_CLKEN_MASK, +	       dev->base + CLKEN_OFFSET); +} + +static void bcm_kona_i2c_config_timing_hs(struct bcm_kona_i2c_dev *dev) +{ +	writel((dev->hs_cfg->prescale << TIM_PRESCALE_SHIFT) | +	       (dev->hs_cfg->time_p << TIM_P_SHIFT) | +	       (dev->hs_cfg->no_div << TIM_NO_DIV_SHIFT) | +	       (dev->hs_cfg->time_div << TIM_DIV_SHIFT), +	       dev->base + TIM_OFFSET); + +	writel((dev->hs_cfg->hs_hold << HSTIM_HS_HOLD_SHIFT) | +	       (dev->hs_cfg->hs_high_phase << HSTIM_HS_HIGH_PHASE_SHIFT) | +	       (dev->hs_cfg->hs_setup << HSTIM_HS_SETUP_SHIFT), +	       dev->base + HSTIM_OFFSET); + +	writel(readl(dev->base + HSTIM_OFFSET) | HSTIM_HS_MODE_MASK, +	       dev->base + HSTIM_OFFSET); +} + +static int bcm_kona_i2c_switch_to_hs(struct bcm_kona_i2c_dev *dev) +{ +	int rc; + +	/* Send mastercode at standard speed */ +	rc = bcm_kona_i2c_write_byte(dev, MASTERCODE, 1); +	if (rc < 0) { +		pr_err("High speed handshake failed\n"); +		return rc; +	} + +	/* Configure external clock to higher frequency */ +	rc = clk_set_rate(dev->external_clk, HS_EXT_CLK_FREQ); +	if (rc) { +		dev_err(dev->device, "%s: clk_set_rate returned %d\n", +			__func__, rc); +		return rc; +	} + +	/* Reconfigure internal dividers */ +	bcm_kona_i2c_config_timing_hs(dev); + +	/* Send a restart command */ +	rc = bcm_kona_send_i2c_cmd(dev, BCM_CMD_RESTART); +	if (rc < 0) +		dev_err(dev->device, "High speed restart command failed\n"); + +	return rc; +} + +static int bcm_kona_i2c_switch_to_std(struct bcm_kona_i2c_dev *dev) +{ +	int rc; + +	/* Reconfigure internal dividers */ +	bcm_kona_i2c_config_timing(dev); + +	/* Configure external clock to lower frequency */ +	rc = clk_set_rate(dev->external_clk, STD_EXT_CLK_FREQ); +	if (rc) { +		dev_err(dev->device, "%s: clk_set_rate returned %d\n", +			__func__, rc); +	} + +	return rc; +} + +/* Master transfer function */ +static int bcm_kona_i2c_xfer(struct i2c_adapter *adapter, +			     struct i2c_msg msgs[], int num) +{ +	struct bcm_kona_i2c_dev *dev = i2c_get_adapdata(adapter); +	struct i2c_msg *pmsg; +	int rc = 0; +	int i; + +	rc = clk_prepare_enable(dev->external_clk); +	if (rc) { +		dev_err(dev->device, "%s: peri clock enable failed. err %d\n", +			__func__, rc); +		return rc; +	} + +	/* Enable pad output */ +	writel(0, dev->base + PADCTL_OFFSET); + +	/* Enable internal clocks */ +	bcm_kona_i2c_enable_clock(dev); + +	/* Send start command */ +	rc = bcm_kona_send_i2c_cmd(dev, BCM_CMD_START); +	if (rc < 0) { +		dev_err(dev->device, "Start command failed rc = %d\n", rc); +		goto xfer_disable_pad; +	} + +	/* Switch to high speed if applicable */ +	if (dev->hs_cfg) { +		rc = bcm_kona_i2c_switch_to_hs(dev); +		if (rc < 0) +			goto xfer_send_stop; +	} + +	/* Loop through all messages */ +	for (i = 0; i < num; i++) { +		pmsg = &msgs[i]; + +		/* Send restart for subsequent messages */ +		if ((i != 0) && ((pmsg->flags & I2C_M_NOSTART) == 0)) { +			rc = bcm_kona_send_i2c_cmd(dev, BCM_CMD_RESTART); +			if (rc < 0) { +				dev_err(dev->device, +					"restart cmd failed rc = %d\n", rc); +					goto xfer_send_stop; +			} +		} + +		/* Send slave address */ +		if (!(pmsg->flags & I2C_M_NOSTART)) { +			rc = bcm_kona_i2c_do_addr(dev, pmsg); +			if (rc < 0) { +				dev_err(dev->device, +					"NAK from addr %2.2x msg#%d rc = %d\n", +					pmsg->addr, i, rc); +				goto xfer_send_stop; +			} +		} + +		/* Perform data transfer */ +		if (pmsg->flags & I2C_M_RD) { +			rc = bcm_kona_i2c_read_fifo(dev, pmsg); +			if (rc < 0) { +				dev_err(dev->device, "read failure\n"); +				goto xfer_send_stop; +			} +		} else { +			rc = bcm_kona_i2c_write_fifo(dev, pmsg); +			if (rc < 0) { +				dev_err(dev->device, "write failure"); +				goto xfer_send_stop; +			} +		} +	} + +	rc = num; + +xfer_send_stop: +	/* Send a STOP command */ +	bcm_kona_send_i2c_cmd(dev, BCM_CMD_STOP); + +	/* Return from high speed if applicable */ +	if (dev->hs_cfg) { +		int hs_rc = bcm_kona_i2c_switch_to_std(dev); + +		if (hs_rc) +			rc = hs_rc; +	} + +xfer_disable_pad: +	/* Disable pad output */ +	writel(PADCTL_PAD_OUT_EN_MASK, dev->base + PADCTL_OFFSET); + +	/* Stop internal clock */ +	bcm_kona_i2c_disable_clock(dev); + +	clk_disable_unprepare(dev->external_clk); + +	return rc; +} + +static uint32_t bcm_kona_i2c_functionality(struct i2c_adapter *adap) +{ +	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | +	    I2C_FUNC_NOSTART; +} + +static const struct i2c_algorithm bcm_algo = { +	.master_xfer = bcm_kona_i2c_xfer, +	.functionality = bcm_kona_i2c_functionality, +}; + +static int bcm_kona_i2c_assign_bus_speed(struct bcm_kona_i2c_dev *dev) +{ +	unsigned int bus_speed; +	int ret = of_property_read_u32(dev->device->of_node, "clock-frequency", +				       &bus_speed); +	if (ret < 0) { +		dev_err(dev->device, "missing clock-frequency property\n"); +		return -ENODEV; +	} + +	switch (bus_speed) { +	case 100000: +		dev->std_cfg = &std_cfg_table[BCM_SPD_100K]; +		break; +	case 400000: +		dev->std_cfg = &std_cfg_table[BCM_SPD_400K]; +		break; +	case 1000000: +		dev->std_cfg = &std_cfg_table[BCM_SPD_1MHZ]; +		break; +	case 3400000: +		/* Send mastercode at 100k */ +		dev->std_cfg = &std_cfg_table[BCM_SPD_100K]; +		dev->hs_cfg = &hs_cfg_table[BCM_SPD_3P4MHZ]; +		break; +	default: +		pr_err("%d hz bus speed not supported\n", bus_speed); +		pr_err("Valid speeds are 100khz, 400khz, 1mhz, and 3.4mhz\n"); +		return -EINVAL; +	} + +	return 0; +} + +static int bcm_kona_i2c_probe(struct platform_device *pdev) +{ +	int rc = 0; +	struct bcm_kona_i2c_dev *dev; +	struct i2c_adapter *adap; +	struct resource *iomem; + +	/* Allocate memory for private data structure */ +	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); +	if (!dev) +		return -ENOMEM; + +	platform_set_drvdata(pdev, dev); +	dev->device = &pdev->dev; +	init_completion(&dev->done); + +	/* Map hardware registers */ +	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	dev->base = devm_ioremap_resource(dev->device, iomem); +	if (IS_ERR(dev->base)) +		return -ENOMEM; + +	/* Get and enable external clock */ +	dev->external_clk = devm_clk_get(dev->device, NULL); +	if (IS_ERR(dev->external_clk)) { +		dev_err(dev->device, "couldn't get clock\n"); +		return -ENODEV; +	} + +	rc = clk_set_rate(dev->external_clk, STD_EXT_CLK_FREQ); +	if (rc) { +		dev_err(dev->device, "%s: clk_set_rate returned %d\n", +			__func__, rc); +		return rc; +	} + +	rc = clk_prepare_enable(dev->external_clk); +	if (rc) { +		dev_err(dev->device, "couldn't enable clock\n"); +		return rc; +	} + +	/* Parse bus speed */ +	rc = bcm_kona_i2c_assign_bus_speed(dev); +	if (rc) +		goto probe_disable_clk; + +	/* Enable internal clocks */ +	bcm_kona_i2c_enable_clock(dev); + +	/* Configure internal dividers */ +	bcm_kona_i2c_config_timing(dev); + +	/* Disable timeout */ +	writel(0, dev->base + TOUT_OFFSET); + +	/* Enable autosense */ +	bcm_kona_i2c_enable_autosense(dev); + +	/* Enable TX FIFO */ +	writel(TXFCR_FIFO_FLUSH_MASK | TXFCR_FIFO_EN_MASK, +	       dev->base + TXFCR_OFFSET); + +	/* Mask all interrupts */ +	writel(0, dev->base + IER_OFFSET); + +	/* Clear all pending interrupts */ +	writel(ISR_CMDBUSY_MASK | +	       ISR_READ_COMPLETE_MASK | +	       ISR_SES_DONE_MASK | +	       ISR_ERR_MASK | +	       ISR_TXFIFOEMPTY_MASK | +	       ISR_NOACK_MASK, +	       dev->base + ISR_OFFSET); + +	/* Get the interrupt number */ +	dev->irq = platform_get_irq(pdev, 0); +	if (dev->irq < 0) { +		dev_err(dev->device, "no irq resource\n"); +		rc = -ENODEV; +		goto probe_disable_clk; +	} + +	/* register the ISR handler */ +	rc = devm_request_irq(&pdev->dev, dev->irq, bcm_kona_i2c_isr, +			      IRQF_SHARED, pdev->name, dev); +	if (rc) { +		dev_err(dev->device, "failed to request irq %i\n", dev->irq); +		goto probe_disable_clk; +	} + +	/* Enable the controller but leave it idle */ +	bcm_kona_i2c_send_cmd_to_ctrl(dev, BCM_CMD_NOACTION); + +	/* Disable pad output */ +	writel(PADCTL_PAD_OUT_EN_MASK, dev->base + PADCTL_OFFSET); + +	/* Disable internal clock */ +	bcm_kona_i2c_disable_clock(dev); + +	/* Disable external clock */ +	clk_disable_unprepare(dev->external_clk); + +	/* Add the i2c adapter */ +	adap = &dev->adapter; +	i2c_set_adapdata(adap, dev); +	adap->owner = THIS_MODULE; +	strlcpy(adap->name, "Broadcom I2C adapter", sizeof(adap->name)); +	adap->algo = &bcm_algo; +	adap->dev.parent = &pdev->dev; +	adap->dev.of_node = pdev->dev.of_node; + +	rc = i2c_add_adapter(adap); +	if (rc) { +		dev_err(dev->device, "failed to add adapter\n"); +		return rc; +	} + +	dev_info(dev->device, "device registered successfully\n"); + +	return 0; + +probe_disable_clk: +	bcm_kona_i2c_disable_clock(dev); +	clk_disable_unprepare(dev->external_clk); + +	return rc; +} + +static int bcm_kona_i2c_remove(struct platform_device *pdev) +{ +	struct bcm_kona_i2c_dev *dev = platform_get_drvdata(pdev); + +	i2c_del_adapter(&dev->adapter); + +	return 0; +} + +static const struct of_device_id bcm_kona_i2c_of_match[] = { +	{.compatible = "brcm,kona-i2c",}, +	{}, +}; +MODULE_DEVICE_TABLE(of, bcm_kona_i2c_of_match); + +static struct platform_driver bcm_kona_i2c_driver = { +	.driver = { +		   .name = "bcm-kona-i2c", +		   .owner = THIS_MODULE, +		   .of_match_table = bcm_kona_i2c_of_match, +		   }, +	.probe = bcm_kona_i2c_probe, +	.remove = bcm_kona_i2c_remove, +}; +module_platform_driver(bcm_kona_i2c_driver); + +MODULE_AUTHOR("Tim Kryger <tkryger@broadcom.com>"); +MODULE_DESCRIPTION("Broadcom Kona I2C Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c index ea4b08fc335..214ff9700ef 100644 --- a/drivers/i2c/busses/i2c-bcm2835.c +++ b/drivers/i2c/busses/i2c-bcm2835.c @@ -151,7 +151,7 @@ static int bcm2835_i2c_xfer_msg(struct bcm2835_i2c_dev *i2c_dev,  	i2c_dev->msg_buf = msg->buf;  	i2c_dev->msg_buf_remaining = msg->len; -	INIT_COMPLETION(i2c_dev->completion); +	reinit_completion(&i2c_dev->completion);  	bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, BCM2835_I2C_C_CLEAR); @@ -219,40 +219,22 @@ static const struct i2c_algorithm bcm2835_i2c_algo = {  static int bcm2835_i2c_probe(struct platform_device *pdev)  {  	struct bcm2835_i2c_dev *i2c_dev; -	struct resource *mem, *requested, *irq; +	struct resource *mem, *irq;  	u32 bus_clk_rate, divider;  	int ret;  	struct i2c_adapter *adap;  	i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); -	if (!i2c_dev) { -		dev_err(&pdev->dev, "Cannot allocate i2c_dev\n"); +	if (!i2c_dev)  		return -ENOMEM; -	}  	platform_set_drvdata(pdev, i2c_dev);  	i2c_dev->dev = &pdev->dev;  	init_completion(&i2c_dev->completion);  	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!mem) { -		dev_err(&pdev->dev, "No mem resource\n"); -		return -ENODEV; -	} - -	requested = devm_request_mem_region(&pdev->dev, mem->start, -					    resource_size(mem), -					    dev_name(&pdev->dev)); -	if (!requested) { -		dev_err(&pdev->dev, "Could not claim register region\n"); -		return -EBUSY; -	} - -	i2c_dev->regs = devm_ioremap(&pdev->dev, mem->start, -				     resource_size(mem)); -	if (!i2c_dev->regs) { -		dev_err(&pdev->dev, "Could not map registers\n"); -		return -ENOMEM; -	} +	i2c_dev->regs = devm_ioremap_resource(&pdev->dev, mem); +	if (IS_ERR(i2c_dev->regs)) +		return PTR_ERR(i2c_dev->regs);  	i2c_dev->clk = devm_clk_get(&pdev->dev, NULL);  	if (IS_ERR(i2c_dev->clk)) { @@ -295,10 +277,11 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)  	adap = &i2c_dev->adapter;  	i2c_set_adapdata(adap, i2c_dev);  	adap->owner = THIS_MODULE; -	adap->class = I2C_CLASS_HWMON; +	adap->class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED;  	strlcpy(adap->name, "bcm2835 I2C adapter", sizeof(adap->name));  	adap->algo = &bcm2835_i2c_algo;  	adap->dev.parent = &pdev->dev; +	adap->dev.of_node = pdev->dev.of_node;  	bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 0); diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index 35a473ba3d8..3e271e7558d 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c @@ -21,10 +21,10 @@  #include <linux/interrupt.h>  #include <linux/platform_device.h>  #include <linux/delay.h> +#include <linux/i2c/bfin_twi.h> -#include <asm/blackfin.h> -#include <asm/portmux.h>  #include <asm/irq.h> +#include <asm/portmux.h>  #include <asm/bfin_twi.h>  /* SMBus mode*/ @@ -65,7 +65,6 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface,  		/* Transmit next data */  		while (iface->writeNum > 0 &&  			(read_FIFO_STAT(iface) & XMTSTAT) != XMT_FULL) { -			SSYNC();  			write_XMT_DATA8(iface, *(iface->transPtr++));  			iface->writeNum--;  		} @@ -248,7 +247,6 @@ static irqreturn_t bfin_twi_interrupt_entry(int irq, void *dev_id)  		/* Clear interrupt status */  		write_INT_STAT(iface, twi_int_status);  		bfin_twi_handle_interrupt(iface, twi_int_status); -		SSYNC();  	}  	spin_unlock_irqrestore(&iface->lock, flags);  	return IRQ_HANDLED; @@ -294,9 +292,7 @@ static int bfin_twi_do_master_xfer(struct i2c_adapter *adap,  	 *  discarded before start a new operation.  	 */  	write_FIFO_CTL(iface, 0x3); -	SSYNC();  	write_FIFO_CTL(iface, 0); -	SSYNC();  	if (pmsg->flags & I2C_M_RD)  		iface->read_write = I2C_SMBUS_READ; @@ -306,7 +302,6 @@ static int bfin_twi_do_master_xfer(struct i2c_adapter *adap,  		if (iface->writeNum > 0) {  			write_XMT_DATA8(iface, *(iface->transPtr++));  			iface->writeNum--; -			SSYNC();  		}  	} @@ -315,7 +310,6 @@ static int bfin_twi_do_master_xfer(struct i2c_adapter *adap,  	/* Interrupt mask . Enable XMT, RCV interrupt */  	write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV); -	SSYNC();  	if (pmsg->len <= 255)  		write_MASTER_CTL(iface, pmsg->len << 6); @@ -329,7 +323,6 @@ static int bfin_twi_do_master_xfer(struct i2c_adapter *adap,  		(iface->msg_num > 1 ? RSTART : 0) |  		((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |  		((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0)); -	SSYNC();  	while (!iface->result) {  		if (!wait_for_completion_timeout(&iface->complete, @@ -453,7 +446,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,  	 * start a new operation.  	 */  	write_FIFO_CTL(iface, 0x3); -	SSYNC();  	write_FIFO_CTL(iface, 0);  	/* clear int stat */ @@ -461,7 +453,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,  	/* Set Transmit device address */  	write_MASTER_ADDR(iface, addr); -	SSYNC();  	switch (iface->cur_mode) {  	case TWI_I2C_MODE_STANDARDSUB: @@ -469,7 +460,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,  		write_INT_MASK(iface, MCOMP | MERR |  			((iface->read_write == I2C_SMBUS_READ) ?  			RCVSERV : XMTSERV)); -		SSYNC();  		if (iface->writeNum + 1 <= 255)  			write_MASTER_CTL(iface, (iface->writeNum + 1) << 6); @@ -484,7 +474,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,  	case TWI_I2C_MODE_COMBINED:  		write_XMT_DATA8(iface, iface->command);  		write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV); -		SSYNC();  		if (iface->writeNum > 0)  			write_MASTER_CTL(iface, (iface->writeNum + 1) << 6); @@ -531,7 +520,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,  		write_INT_MASK(iface, MCOMP | MERR |  			((iface->read_write == I2C_SMBUS_READ) ?  			RCVSERV : XMTSERV)); -		SSYNC();  		/* Master enable */  		write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN | @@ -539,7 +527,6 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,  			((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));  		break;  	} -	SSYNC();  	while (!iface->result) {  		if (!wait_for_completion_timeout(&iface->complete, @@ -633,35 +620,27 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)  	int rc;  	unsigned int clkhilow; -	iface = kzalloc(sizeof(struct bfin_twi_iface), GFP_KERNEL); +	iface = devm_kzalloc(&pdev->dev, sizeof(struct bfin_twi_iface), +			GFP_KERNEL);  	if (!iface) {  		dev_err(&pdev->dev, "Cannot allocate memory\n"); -		rc = -ENOMEM; -		goto out_error_nomem; +		return -ENOMEM;  	}  	spin_lock_init(&(iface->lock));  	/* Find and map our resources */  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (res == NULL) { -		dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); -		rc = -ENOENT; -		goto out_error_get_res; -	} - -	iface->regs_base = ioremap(res->start, resource_size(res)); -	if (iface->regs_base == NULL) { +	iface->regs_base = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(iface->regs_base)) {  		dev_err(&pdev->dev, "Cannot map IO\n"); -		rc = -ENXIO; -		goto out_error_ioremap; +		return PTR_ERR(iface->regs_base);  	}  	iface->irq = platform_get_irq(pdev, 0);  	if (iface->irq < 0) {  		dev_err(&pdev->dev, "No IRQ specified\n"); -		rc = -ENOENT; -		goto out_error_no_irq; +		return -ENOENT;  	}  	p_adap = &iface->adap; @@ -669,25 +648,25 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)  	strlcpy(p_adap->name, pdev->name, sizeof(p_adap->name));  	p_adap->algo = &bfin_twi_algorithm;  	p_adap->algo_data = iface; -	p_adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; +	p_adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED;  	p_adap->dev.parent = &pdev->dev;  	p_adap->timeout = 5 * HZ;  	p_adap->retries = 3;  	rc = peripheral_request_list( -			(unsigned short *)dev_get_platdata(&pdev->dev), +			dev_get_platdata(&pdev->dev),  			"i2c-bfin-twi");  	if (rc) {  		dev_err(&pdev->dev, "Can't setup pin mux!\n"); -		goto out_error_pin_mux; +		return -EBUSY;  	} -	rc = request_irq(iface->irq, bfin_twi_interrupt_entry, +	rc = devm_request_irq(&pdev->dev, iface->irq, bfin_twi_interrupt_entry,  		0, pdev->name, iface);  	if (rc) {  		dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq);  		rc = -ENODEV; -		goto out_error_req_irq; +		goto out_error;  	}  	/* Set TWI internal clock as 10MHz */ @@ -704,12 +683,11 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)  	/* Enable TWI */  	write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA); -	SSYNC();  	rc = i2c_add_numbered_adapter(p_adap);  	if (rc < 0) {  		dev_err(&pdev->dev, "Can't add i2c adapter!\n"); -		goto out_error_add_adapter; +		goto out_error;  	}  	platform_set_drvdata(pdev, iface); @@ -719,17 +697,8 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)  	return 0; -out_error_add_adapter: -	free_irq(iface->irq, iface); -out_error_req_irq: -out_error_no_irq: -	peripheral_free_list((unsigned short *)dev_get_platdata(&pdev->dev)); -out_error_pin_mux: -	iounmap(iface->regs_base); -out_error_ioremap: -out_error_get_res: -	kfree(iface); -out_error_nomem: +out_error: +	peripheral_free_list(dev_get_platdata(&pdev->dev));  	return rc;  } @@ -738,10 +707,7 @@ static int i2c_bfin_twi_remove(struct platform_device *pdev)  	struct bfin_twi_iface *iface = platform_get_drvdata(pdev);  	i2c_del_adapter(&(iface->adap)); -	free_irq(iface->irq, iface); -	peripheral_free_list((unsigned short *)dev_get_platdata(&pdev->dev)); -	iounmap(iface->regs_base); -	kfree(iface); +	peripheral_free_list(dev_get_platdata(&pdev->dev));  	return 0;  } diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c new file mode 100644 index 00000000000..63f3f03ecc9 --- /dev/null +++ b/drivers/i2c/busses/i2c-cadence.c @@ -0,0 +1,905 @@ +/* + * I2C bus driver for the Cadence I2C controller. + * + * Copyright (C) 2009 - 2014 Xilinx, Inc. + * + * 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/clk.h> +#include <linux/delay.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +/* Register offsets for the I2C device. */ +#define CDNS_I2C_CR_OFFSET		0x00 /* Control Register, RW */ +#define CDNS_I2C_SR_OFFSET		0x04 /* Status Register, RO */ +#define CDNS_I2C_ADDR_OFFSET		0x08 /* I2C Address Register, RW */ +#define CDNS_I2C_DATA_OFFSET		0x0C /* I2C Data Register, RW */ +#define CDNS_I2C_ISR_OFFSET		0x10 /* IRQ Status Register, RW */ +#define CDNS_I2C_XFER_SIZE_OFFSET	0x14 /* Transfer Size Register, RW */ +#define CDNS_I2C_TIME_OUT_OFFSET	0x1C /* Time Out Register, RW */ +#define CDNS_I2C_IER_OFFSET		0x24 /* IRQ Enable Register, WO */ +#define CDNS_I2C_IDR_OFFSET		0x28 /* IRQ Disable Register, WO */ + +/* Control Register Bit mask definitions */ +#define CDNS_I2C_CR_HOLD		BIT(4) /* Hold Bus bit */ +#define CDNS_I2C_CR_ACK_EN		BIT(3) +#define CDNS_I2C_CR_NEA			BIT(2) +#define CDNS_I2C_CR_MS			BIT(1) +/* Read or Write Master transfer 0 = Transmitter, 1 = Receiver */ +#define CDNS_I2C_CR_RW			BIT(0) +/* 1 = Auto init FIFO to zeroes */ +#define CDNS_I2C_CR_CLR_FIFO		BIT(6) +#define CDNS_I2C_CR_DIVA_SHIFT		14 +#define CDNS_I2C_CR_DIVA_MASK		(3 << CDNS_I2C_CR_DIVA_SHIFT) +#define CDNS_I2C_CR_DIVB_SHIFT		8 +#define CDNS_I2C_CR_DIVB_MASK		(0x3f << CDNS_I2C_CR_DIVB_SHIFT) + +/* Status Register Bit mask definitions */ +#define CDNS_I2C_SR_BA		BIT(8) +#define CDNS_I2C_SR_RXDV	BIT(5) + +/* + * I2C Address Register Bit mask definitions + * Normal addressing mode uses [6:0] bits. Extended addressing mode uses [9:0] + * bits. A write access to this register always initiates a transfer if the I2C + * is in master mode. + */ +#define CDNS_I2C_ADDR_MASK	0x000003FF /* I2C Address Mask */ + +/* + * I2C Interrupt Registers Bit mask definitions + * All the four interrupt registers (Status/Mask/Enable/Disable) have the same + * bit definitions. + */ +#define CDNS_I2C_IXR_ARB_LOST		BIT(9) +#define CDNS_I2C_IXR_RX_UNF		BIT(7) +#define CDNS_I2C_IXR_TX_OVF		BIT(6) +#define CDNS_I2C_IXR_RX_OVF		BIT(5) +#define CDNS_I2C_IXR_SLV_RDY		BIT(4) +#define CDNS_I2C_IXR_TO			BIT(3) +#define CDNS_I2C_IXR_NACK		BIT(2) +#define CDNS_I2C_IXR_DATA		BIT(1) +#define CDNS_I2C_IXR_COMP		BIT(0) + +#define CDNS_I2C_IXR_ALL_INTR_MASK	(CDNS_I2C_IXR_ARB_LOST | \ +					 CDNS_I2C_IXR_RX_UNF | \ +					 CDNS_I2C_IXR_TX_OVF | \ +					 CDNS_I2C_IXR_RX_OVF | \ +					 CDNS_I2C_IXR_SLV_RDY | \ +					 CDNS_I2C_IXR_TO | \ +					 CDNS_I2C_IXR_NACK | \ +					 CDNS_I2C_IXR_DATA | \ +					 CDNS_I2C_IXR_COMP) + +#define CDNS_I2C_IXR_ERR_INTR_MASK	(CDNS_I2C_IXR_ARB_LOST | \ +					 CDNS_I2C_IXR_RX_UNF | \ +					 CDNS_I2C_IXR_TX_OVF | \ +					 CDNS_I2C_IXR_RX_OVF | \ +					 CDNS_I2C_IXR_NACK) + +#define CDNS_I2C_ENABLED_INTR_MASK	(CDNS_I2C_IXR_ARB_LOST | \ +					 CDNS_I2C_IXR_RX_UNF | \ +					 CDNS_I2C_IXR_TX_OVF | \ +					 CDNS_I2C_IXR_RX_OVF | \ +					 CDNS_I2C_IXR_NACK | \ +					 CDNS_I2C_IXR_DATA | \ +					 CDNS_I2C_IXR_COMP) + +#define CDNS_I2C_TIMEOUT		msecs_to_jiffies(1000) + +#define CDNS_I2C_FIFO_DEPTH		16 +/* FIFO depth at which the DATA interrupt occurs */ +#define CDNS_I2C_DATA_INTR_DEPTH	(CDNS_I2C_FIFO_DEPTH - 2) +#define CDNS_I2C_MAX_TRANSFER_SIZE	255 +/* Transfer size in multiples of data interrupt depth */ +#define CDNS_I2C_TRANSFER_SIZE	(CDNS_I2C_MAX_TRANSFER_SIZE - 3) + +#define DRIVER_NAME		"cdns-i2c" + +#define CDNS_I2C_SPEED_MAX	400000 +#define CDNS_I2C_SPEED_DEFAULT	100000 + +#define CDNS_I2C_DIVA_MAX	4 +#define CDNS_I2C_DIVB_MAX	64 + +#define cdns_i2c_readreg(offset)       readl_relaxed(id->membase + offset) +#define cdns_i2c_writereg(val, offset) writel_relaxed(val, id->membase + offset) + +/** + * struct cdns_i2c - I2C device private data structure + * @membase:		Base address of the I2C device + * @adap:		I2C adapter instance + * @p_msg:		Message pointer + * @err_status:		Error status in Interrupt Status Register + * @xfer_done:		Transfer complete status + * @p_send_buf:		Pointer to transmit buffer + * @p_recv_buf:		Pointer to receive buffer + * @suspended:		Flag holding the device's PM status + * @send_count:		Number of bytes still expected to send + * @recv_count:		Number of bytes still expected to receive + * @irq:		IRQ number + * @input_clk:		Input clock to I2C controller + * @i2c_clk:		Maximum I2C clock speed + * @bus_hold_flag:	Flag used in repeated start for clearing HOLD bit + * @clk:		Pointer to struct clk + * @clk_rate_change_nb:	Notifier block for clock rate changes + */ +struct cdns_i2c { +	void __iomem *membase; +	struct i2c_adapter adap; +	struct i2c_msg *p_msg; +	int err_status; +	struct completion xfer_done; +	unsigned char *p_send_buf; +	unsigned char *p_recv_buf; +	u8 suspended; +	unsigned int send_count; +	unsigned int recv_count; +	int irq; +	unsigned long input_clk; +	unsigned int i2c_clk; +	unsigned int bus_hold_flag; +	struct clk *clk; +	struct notifier_block clk_rate_change_nb; +}; + +#define to_cdns_i2c(_nb)	container_of(_nb, struct cdns_i2c, \ +					     clk_rate_change_nb) + +/** + * cdns_i2c_clear_bus_hold() - Clear bus hold bit + * @id:	Pointer to driver data struct + * + * Helper to clear the controller's bus hold bit. + */ +static void cdns_i2c_clear_bus_hold(struct cdns_i2c *id) +{ +	u32 reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET); +	if (reg & CDNS_I2C_CR_HOLD) +		cdns_i2c_writereg(reg & ~CDNS_I2C_CR_HOLD, CDNS_I2C_CR_OFFSET); +} + +/** + * cdns_i2c_isr - Interrupt handler for the I2C device + * @irq:	irq number for the I2C device + * @ptr:	void pointer to cdns_i2c structure + * + * This function handles the data interrupt, transfer complete interrupt and + * the error interrupts of the I2C device. + * + * Return: IRQ_HANDLED always + */ +static irqreturn_t cdns_i2c_isr(int irq, void *ptr) +{ +	unsigned int isr_status, avail_bytes; +	unsigned int bytes_to_recv, bytes_to_send; +	struct cdns_i2c *id = ptr; +	/* Signal completion only after everything is updated */ +	int done_flag = 0; +	irqreturn_t status = IRQ_NONE; + +	isr_status = cdns_i2c_readreg(CDNS_I2C_ISR_OFFSET); + +	/* Handling nack and arbitration lost interrupt */ +	if (isr_status & (CDNS_I2C_IXR_NACK | CDNS_I2C_IXR_ARB_LOST)) { +		done_flag = 1; +		status = IRQ_HANDLED; +	} + +	/* Handling Data interrupt */ +	if ((isr_status & CDNS_I2C_IXR_DATA) && +			(id->recv_count >= CDNS_I2C_DATA_INTR_DEPTH)) { +		/* Always read data interrupt threshold bytes */ +		bytes_to_recv = CDNS_I2C_DATA_INTR_DEPTH; +		id->recv_count -= CDNS_I2C_DATA_INTR_DEPTH; +		avail_bytes = cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET); + +		/* +		 * if the tranfer size register value is zero, then +		 * check for the remaining bytes and update the +		 * transfer size register. +		 */ +		if (!avail_bytes) { +			if (id->recv_count > CDNS_I2C_TRANSFER_SIZE) +				cdns_i2c_writereg(CDNS_I2C_TRANSFER_SIZE, +						CDNS_I2C_XFER_SIZE_OFFSET); +			else +				cdns_i2c_writereg(id->recv_count, +						CDNS_I2C_XFER_SIZE_OFFSET); +		} + +		/* Process the data received */ +		while (bytes_to_recv--) +			*(id->p_recv_buf)++ = +				cdns_i2c_readreg(CDNS_I2C_DATA_OFFSET); + +		if (!id->bus_hold_flag && +				(id->recv_count <= CDNS_I2C_FIFO_DEPTH)) +			cdns_i2c_clear_bus_hold(id); + +		status = IRQ_HANDLED; +	} + +	/* Handling Transfer Complete interrupt */ +	if (isr_status & CDNS_I2C_IXR_COMP) { +		if (!id->p_recv_buf) { +			/* +			 * If the device is sending data If there is further +			 * data to be sent. Calculate the available space +			 * in FIFO and fill the FIFO with that many bytes. +			 */ +			if (id->send_count) { +				avail_bytes = CDNS_I2C_FIFO_DEPTH - +				    cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET); +				if (id->send_count > avail_bytes) +					bytes_to_send = avail_bytes; +				else +					bytes_to_send = id->send_count; + +				while (bytes_to_send--) { +					cdns_i2c_writereg( +						(*(id->p_send_buf)++), +						 CDNS_I2C_DATA_OFFSET); +					id->send_count--; +				} +			} else { +				/* +				 * Signal the completion of transaction and +				 * clear the hold bus bit if there are no +				 * further messages to be processed. +				 */ +				done_flag = 1; +			} +			if (!id->send_count && !id->bus_hold_flag) +				cdns_i2c_clear_bus_hold(id); +		} else { +			if (!id->bus_hold_flag) +				cdns_i2c_clear_bus_hold(id); +			/* +			 * If the device is receiving data, then signal +			 * the completion of transaction and read the data +			 * present in the FIFO. Signal the completion of +			 * transaction. +			 */ +			while (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) & +					CDNS_I2C_SR_RXDV) { +				*(id->p_recv_buf)++ = +					cdns_i2c_readreg(CDNS_I2C_DATA_OFFSET); +				id->recv_count--; +			} +			done_flag = 1; +		} + +		status = IRQ_HANDLED; +	} + +	/* Update the status for errors */ +	id->err_status = isr_status & CDNS_I2C_IXR_ERR_INTR_MASK; +	if (id->err_status) +		status = IRQ_HANDLED; + +	cdns_i2c_writereg(isr_status, CDNS_I2C_ISR_OFFSET); + +	if (done_flag) +		complete(&id->xfer_done); + +	return status; +} + +/** + * cdns_i2c_mrecv - Prepare and start a master receive operation + * @id:		pointer to the i2c device structure + */ +static void cdns_i2c_mrecv(struct cdns_i2c *id) +{ +	unsigned int ctrl_reg; +	unsigned int isr_status; + +	id->p_recv_buf = id->p_msg->buf; +	id->recv_count = id->p_msg->len; + +	/* Put the controller in master receive mode and clear the FIFO */ +	ctrl_reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET); +	ctrl_reg |= CDNS_I2C_CR_RW | CDNS_I2C_CR_CLR_FIFO; + +	if (id->p_msg->flags & I2C_M_RECV_LEN) +		id->recv_count = I2C_SMBUS_BLOCK_MAX + 1; + +	/* +	 * Check for the message size against FIFO depth and set the +	 * 'hold bus' bit if it is greater than FIFO depth. +	 */ +	if (id->recv_count > CDNS_I2C_FIFO_DEPTH) +		ctrl_reg |= CDNS_I2C_CR_HOLD; + +	cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); + +	/* Clear the interrupts in interrupt status register */ +	isr_status = cdns_i2c_readreg(CDNS_I2C_ISR_OFFSET); +	cdns_i2c_writereg(isr_status, CDNS_I2C_ISR_OFFSET); + +	/* +	 * The no. of bytes to receive is checked against the limit of +	 * max transfer size. Set transfer size register with no of bytes +	 * receive if it is less than transfer size and transfer size if +	 * it is more. Enable the interrupts. +	 */ +	if (id->recv_count > CDNS_I2C_TRANSFER_SIZE) +		cdns_i2c_writereg(CDNS_I2C_TRANSFER_SIZE, +				  CDNS_I2C_XFER_SIZE_OFFSET); +	else +		cdns_i2c_writereg(id->recv_count, CDNS_I2C_XFER_SIZE_OFFSET); +	/* Clear the bus hold flag if bytes to receive is less than FIFO size */ +	if (!id->bus_hold_flag && +		((id->p_msg->flags & I2C_M_RECV_LEN) != I2C_M_RECV_LEN) && +		(id->recv_count <= CDNS_I2C_FIFO_DEPTH)) +			cdns_i2c_clear_bus_hold(id); +	/* Set the slave address in address register - triggers operation */ +	cdns_i2c_writereg(id->p_msg->addr & CDNS_I2C_ADDR_MASK, +						CDNS_I2C_ADDR_OFFSET); +	cdns_i2c_writereg(CDNS_I2C_ENABLED_INTR_MASK, CDNS_I2C_IER_OFFSET); +} + +/** + * cdns_i2c_msend - Prepare and start a master send operation + * @id:		pointer to the i2c device + */ +static void cdns_i2c_msend(struct cdns_i2c *id) +{ +	unsigned int avail_bytes; +	unsigned int bytes_to_send; +	unsigned int ctrl_reg; +	unsigned int isr_status; + +	id->p_recv_buf = NULL; +	id->p_send_buf = id->p_msg->buf; +	id->send_count = id->p_msg->len; + +	/* Set the controller in Master transmit mode and clear the FIFO. */ +	ctrl_reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET); +	ctrl_reg &= ~CDNS_I2C_CR_RW; +	ctrl_reg |= CDNS_I2C_CR_CLR_FIFO; + +	/* +	 * Check for the message size against FIFO depth and set the +	 * 'hold bus' bit if it is greater than FIFO depth. +	 */ +	if (id->send_count > CDNS_I2C_FIFO_DEPTH) +		ctrl_reg |= CDNS_I2C_CR_HOLD; +	cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); + +	/* Clear the interrupts in interrupt status register. */ +	isr_status = cdns_i2c_readreg(CDNS_I2C_ISR_OFFSET); +	cdns_i2c_writereg(isr_status, CDNS_I2C_ISR_OFFSET); + +	/* +	 * Calculate the space available in FIFO. Check the message length +	 * against the space available, and fill the FIFO accordingly. +	 * Enable the interrupts. +	 */ +	avail_bytes = CDNS_I2C_FIFO_DEPTH - +				cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET); + +	if (id->send_count > avail_bytes) +		bytes_to_send = avail_bytes; +	else +		bytes_to_send = id->send_count; + +	while (bytes_to_send--) { +		cdns_i2c_writereg((*(id->p_send_buf)++), CDNS_I2C_DATA_OFFSET); +		id->send_count--; +	} + +	/* +	 * Clear the bus hold flag if there is no more data +	 * and if it is the last message. +	 */ +	if (!id->bus_hold_flag && !id->send_count) +		cdns_i2c_clear_bus_hold(id); +	/* Set the slave address in address register - triggers operation. */ +	cdns_i2c_writereg(id->p_msg->addr & CDNS_I2C_ADDR_MASK, +						CDNS_I2C_ADDR_OFFSET); + +	cdns_i2c_writereg(CDNS_I2C_ENABLED_INTR_MASK, CDNS_I2C_IER_OFFSET); +} + +/** + * cdns_i2c_master_reset - Reset the interface + * @adap:	pointer to the i2c adapter driver instance + * + * This function cleanup the fifos, clear the hold bit and status + * and disable the interrupts. + */ +static void cdns_i2c_master_reset(struct i2c_adapter *adap) +{ +	struct cdns_i2c *id = adap->algo_data; +	u32 regval; + +	/* Disable the interrupts */ +	cdns_i2c_writereg(CDNS_I2C_IXR_ALL_INTR_MASK, CDNS_I2C_IDR_OFFSET); +	/* Clear the hold bit and fifos */ +	regval = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET); +	regval &= ~CDNS_I2C_CR_HOLD; +	regval |= CDNS_I2C_CR_CLR_FIFO; +	cdns_i2c_writereg(regval, CDNS_I2C_CR_OFFSET); +	/* Update the transfercount register to zero */ +	cdns_i2c_writereg(0, CDNS_I2C_XFER_SIZE_OFFSET); +	/* Clear the interupt status register */ +	regval = cdns_i2c_readreg(CDNS_I2C_ISR_OFFSET); +	cdns_i2c_writereg(regval, CDNS_I2C_ISR_OFFSET); +	/* Clear the status register */ +	regval = cdns_i2c_readreg(CDNS_I2C_SR_OFFSET); +	cdns_i2c_writereg(regval, CDNS_I2C_SR_OFFSET); +} + +static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg, +		struct i2c_adapter *adap) +{ +	int ret; +	u32 reg; + +	id->p_msg = msg; +	id->err_status = 0; +	reinit_completion(&id->xfer_done); + +	/* Check for the TEN Bit mode on each msg */ +	reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET); +	if (msg->flags & I2C_M_TEN) { +		if (reg & CDNS_I2C_CR_NEA) +			cdns_i2c_writereg(reg & ~CDNS_I2C_CR_NEA, +					CDNS_I2C_CR_OFFSET); +	} else { +		if (!(reg & CDNS_I2C_CR_NEA)) +			cdns_i2c_writereg(reg | CDNS_I2C_CR_NEA, +					CDNS_I2C_CR_OFFSET); +	} + +	/* Check for the R/W flag on each msg */ +	if (msg->flags & I2C_M_RD) +		cdns_i2c_mrecv(id); +	else +		cdns_i2c_msend(id); + +	/* Wait for the signal of completion */ +	ret = wait_for_completion_timeout(&id->xfer_done, adap->timeout); +	if (!ret) { +		cdns_i2c_master_reset(adap); +		dev_err(id->adap.dev.parent, +				"timeout waiting on completion\n"); +		return -ETIMEDOUT; +	} + +	cdns_i2c_writereg(CDNS_I2C_IXR_ALL_INTR_MASK, +			  CDNS_I2C_IDR_OFFSET); + +	/* If it is bus arbitration error, try again */ +	if (id->err_status & CDNS_I2C_IXR_ARB_LOST) +		return -EAGAIN; + +	return 0; +} + +/** + * cdns_i2c_master_xfer - The main i2c transfer function + * @adap:	pointer to the i2c adapter driver instance + * @msgs:	pointer to the i2c message structure + * @num:	the number of messages to transfer + * + * Initiates the send/recv activity based on the transfer message received. + * + * Return: number of msgs processed on success, negative error otherwise + */ +static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, +				int num) +{ +	int ret, count; +	u32 reg; +	struct cdns_i2c *id = adap->algo_data; + +	/* Check if the bus is free */ +	if (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) & CDNS_I2C_SR_BA) +		return -EAGAIN; + +	/* +	 * Set the flag to one when multiple messages are to be +	 * processed with a repeated start. +	 */ +	if (num > 1) { +		id->bus_hold_flag = 1; +		reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET); +		reg |= CDNS_I2C_CR_HOLD; +		cdns_i2c_writereg(reg, CDNS_I2C_CR_OFFSET); +	} else { +		id->bus_hold_flag = 0; +	} + +	/* Process the msg one by one */ +	for (count = 0; count < num; count++, msgs++) { +		if (count == (num - 1)) +			id->bus_hold_flag = 0; + +		ret = cdns_i2c_process_msg(id, msgs, adap); +		if (ret) +			return ret; + +		/* Report the other error interrupts to application */ +		if (id->err_status) { +			cdns_i2c_master_reset(adap); + +			if (id->err_status & CDNS_I2C_IXR_NACK) +				return -ENXIO; + +			return -EIO; +		} +	} + +	return num; +} + +/** + * cdns_i2c_func - Returns the supported features of the I2C driver + * @adap:	pointer to the i2c adapter structure + * + * Return: 32 bit value, each bit corresponding to a feature + */ +static u32 cdns_i2c_func(struct i2c_adapter *adap) +{ +	return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | +		(I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) | +		I2C_FUNC_SMBUS_BLOCK_DATA; +} + +static const struct i2c_algorithm cdns_i2c_algo = { +	.master_xfer	= cdns_i2c_master_xfer, +	.functionality	= cdns_i2c_func, +}; + +/** + * cdns_i2c_calc_divs - Calculate clock dividers + * @f:		I2C clock frequency + * @input_clk:	Input clock frequency + * @a:		First divider (return value) + * @b:		Second divider (return value) + * + * f is used as input and output variable. As input it is used as target I2C + * frequency. On function exit f holds the actually resulting I2C frequency. + * + * Return: 0 on success, negative errno otherwise. + */ +static int cdns_i2c_calc_divs(unsigned long *f, unsigned long input_clk, +		unsigned int *a, unsigned int *b) +{ +	unsigned long fscl = *f, best_fscl = *f, actual_fscl, temp; +	unsigned int div_a, div_b, calc_div_a = 0, calc_div_b = 0; +	unsigned int last_error, current_error; + +	/* calculate (divisor_a+1) x (divisor_b+1) */ +	temp = input_clk / (22 * fscl); + +	/* +	 * If the calculated value is negative or 0, the fscl input is out of +	 * range. Return error. +	 */ +	if (!temp || (temp > (CDNS_I2C_DIVA_MAX * CDNS_I2C_DIVB_MAX))) +		return -EINVAL; + +	last_error = -1; +	for (div_a = 0; div_a < CDNS_I2C_DIVA_MAX; div_a++) { +		div_b = DIV_ROUND_UP(input_clk, 22 * fscl * (div_a + 1)); + +		if ((div_b < 1) || (div_b > CDNS_I2C_DIVB_MAX)) +			continue; +		div_b--; + +		actual_fscl = input_clk / (22 * (div_a + 1) * (div_b + 1)); + +		if (actual_fscl > fscl) +			continue; + +		current_error = ((actual_fscl > fscl) ? (actual_fscl - fscl) : +							(fscl - actual_fscl)); + +		if (last_error > current_error) { +			calc_div_a = div_a; +			calc_div_b = div_b; +			best_fscl = actual_fscl; +			last_error = current_error; +		} +	} + +	*a = calc_div_a; +	*b = calc_div_b; +	*f = best_fscl; + +	return 0; +} + +/** + * cdns_i2c_setclk - This function sets the serial clock rate for the I2C device + * @clk_in:	I2C clock input frequency in Hz + * @id:		Pointer to the I2C device structure + * + * The device must be idle rather than busy transferring data before setting + * these device options. + * The data rate is set by values in the control register. + * The formula for determining the correct register values is + *	Fscl = Fpclk/(22 x (divisor_a+1) x (divisor_b+1)) + * See the hardware data sheet for a full explanation of setting the serial + * clock rate. The clock can not be faster than the input clock divide by 22. + * The two most common clock rates are 100KHz and 400KHz. + * + * Return: 0 on success, negative error otherwise + */ +static int cdns_i2c_setclk(unsigned long clk_in, struct cdns_i2c *id) +{ +	unsigned int div_a, div_b; +	unsigned int ctrl_reg; +	int ret = 0; +	unsigned long fscl = id->i2c_clk; + +	ret = cdns_i2c_calc_divs(&fscl, clk_in, &div_a, &div_b); +	if (ret) +		return ret; + +	ctrl_reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET); +	ctrl_reg &= ~(CDNS_I2C_CR_DIVA_MASK | CDNS_I2C_CR_DIVB_MASK); +	ctrl_reg |= ((div_a << CDNS_I2C_CR_DIVA_SHIFT) | +			(div_b << CDNS_I2C_CR_DIVB_SHIFT)); +	cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); + +	return 0; +} + +/** + * cdns_i2c_clk_notifier_cb - Clock rate change callback + * @nb:		Pointer to notifier block + * @event:	Notification reason + * @data:	Pointer to notification data object + * + * This function is called when the cdns_i2c input clock frequency changes. + * The callback checks whether a valid bus frequency can be generated after the + * change. If so, the change is acknowledged, otherwise the change is aborted. + * New dividers are written to the HW in the pre- or post change notification + * depending on the scaling direction. + * + * Return:	NOTIFY_STOP if the rate change should be aborted, NOTIFY_OK + *		to acknowedge the change, NOTIFY_DONE if the notification is + *		considered irrelevant. + */ +static int cdns_i2c_clk_notifier_cb(struct notifier_block *nb, unsigned long +		event, void *data) +{ +	struct clk_notifier_data *ndata = data; +	struct cdns_i2c *id = to_cdns_i2c(nb); + +	if (id->suspended) +		return NOTIFY_OK; + +	switch (event) { +	case PRE_RATE_CHANGE: +	{ +		unsigned long input_clk = ndata->new_rate; +		unsigned long fscl = id->i2c_clk; +		unsigned int div_a, div_b; +		int ret; + +		ret = cdns_i2c_calc_divs(&fscl, input_clk, &div_a, &div_b); +		if (ret) { +			dev_warn(id->adap.dev.parent, +					"clock rate change rejected\n"); +			return NOTIFY_STOP; +		} + +		/* scale up */ +		if (ndata->new_rate > ndata->old_rate) +			cdns_i2c_setclk(ndata->new_rate, id); + +		return NOTIFY_OK; +	} +	case POST_RATE_CHANGE: +		id->input_clk = ndata->new_rate; +		/* scale down */ +		if (ndata->new_rate < ndata->old_rate) +			cdns_i2c_setclk(ndata->new_rate, id); +		return NOTIFY_OK; +	case ABORT_RATE_CHANGE: +		/* scale up */ +		if (ndata->new_rate > ndata->old_rate) +			cdns_i2c_setclk(ndata->old_rate, id); +		return NOTIFY_OK; +	default: +		return NOTIFY_DONE; +	} +} + +/** + * cdns_i2c_suspend - Suspend method for the driver + * @_dev:	Address of the platform_device structure + * + * Put the driver into low power mode. + * + * Return: 0 always + */ +static int __maybe_unused cdns_i2c_suspend(struct device *_dev) +{ +	struct platform_device *pdev = container_of(_dev, +			struct platform_device, dev); +	struct cdns_i2c *xi2c = platform_get_drvdata(pdev); + +	clk_disable(xi2c->clk); +	xi2c->suspended = 1; + +	return 0; +} + +/** + * cdns_i2c_resume - Resume from suspend + * @_dev:	Address of the platform_device structure + * + * Resume operation after suspend. + * + * Return: 0 on success and error value on error + */ +static int __maybe_unused cdns_i2c_resume(struct device *_dev) +{ +	struct platform_device *pdev = container_of(_dev, +			struct platform_device, dev); +	struct cdns_i2c *xi2c = platform_get_drvdata(pdev); +	int ret; + +	ret = clk_enable(xi2c->clk); +	if (ret) { +		dev_err(_dev, "Cannot enable clock.\n"); +		return ret; +	} + +	xi2c->suspended = 0; + +	return 0; +} + +static SIMPLE_DEV_PM_OPS(cdns_i2c_dev_pm_ops, cdns_i2c_suspend, +			 cdns_i2c_resume); + +/** + * cdns_i2c_probe - Platform registration call + * @pdev:	Handle to the platform device structure + * + * This function does all the memory allocation and registration for the i2c + * device. User can modify the address mode to 10 bit address mode using the + * ioctl call with option I2C_TENBIT. + * + * Return: 0 on success, negative error otherwise + */ +static int cdns_i2c_probe(struct platform_device *pdev) +{ +	struct resource *r_mem; +	struct cdns_i2c *id; +	int ret; + +	id = devm_kzalloc(&pdev->dev, sizeof(*id), GFP_KERNEL); +	if (!id) +		return -ENOMEM; + +	platform_set_drvdata(pdev, id); + +	r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	id->membase = devm_ioremap_resource(&pdev->dev, r_mem); +	if (IS_ERR(id->membase)) +		return PTR_ERR(id->membase); + +	id->irq = platform_get_irq(pdev, 0); + +	id->adap.dev.of_node = pdev->dev.of_node; +	id->adap.algo = &cdns_i2c_algo; +	id->adap.timeout = CDNS_I2C_TIMEOUT; +	id->adap.retries = 3;		/* Default retry value. */ +	id->adap.algo_data = id; +	id->adap.dev.parent = &pdev->dev; +	init_completion(&id->xfer_done); +	snprintf(id->adap.name, sizeof(id->adap.name), +		 "Cadence I2C at %08lx", (unsigned long)r_mem->start); + +	id->clk = devm_clk_get(&pdev->dev, NULL); +	if (IS_ERR(id->clk)) { +		dev_err(&pdev->dev, "input clock not found.\n"); +		return PTR_ERR(id->clk); +	} +	ret = clk_prepare_enable(id->clk); +	if (ret) { +		dev_err(&pdev->dev, "Unable to enable clock.\n"); +		return ret; +	} +	id->clk_rate_change_nb.notifier_call = cdns_i2c_clk_notifier_cb; +	if (clk_notifier_register(id->clk, &id->clk_rate_change_nb)) +		dev_warn(&pdev->dev, "Unable to register clock notifier.\n"); +	id->input_clk = clk_get_rate(id->clk); + +	ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", +			&id->i2c_clk); +	if (ret || (id->i2c_clk > CDNS_I2C_SPEED_MAX)) +		id->i2c_clk = CDNS_I2C_SPEED_DEFAULT; + +	cdns_i2c_writereg(CDNS_I2C_CR_ACK_EN | CDNS_I2C_CR_NEA | CDNS_I2C_CR_MS, +			  CDNS_I2C_CR_OFFSET); + +	ret = cdns_i2c_setclk(id->input_clk, id); +	if (ret) { +		dev_err(&pdev->dev, "invalid SCL clock: %u Hz\n", id->i2c_clk); +		ret = -EINVAL; +		goto err_clk_dis; +	} + +	ret = devm_request_irq(&pdev->dev, id->irq, cdns_i2c_isr, 0, +				 DRIVER_NAME, id); +	if (ret) { +		dev_err(&pdev->dev, "cannot get irq %d\n", id->irq); +		goto err_clk_dis; +	} + +	ret = i2c_add_adapter(&id->adap); +	if (ret < 0) { +		dev_err(&pdev->dev, "reg adap failed: %d\n", ret); +		goto err_clk_dis; +	} + +	dev_info(&pdev->dev, "%u kHz mmio %08lx irq %d\n", +		 id->i2c_clk / 1000, (unsigned long)r_mem->start, id->irq); + +	return 0; + +err_clk_dis: +	clk_disable_unprepare(id->clk); +	return ret; +} + +/** + * cdns_i2c_remove - Unregister the device after releasing the resources + * @pdev:	Handle to the platform device structure + * + * This function frees all the resources allocated to the device. + * + * Return: 0 always + */ +static int cdns_i2c_remove(struct platform_device *pdev) +{ +	struct cdns_i2c *id = platform_get_drvdata(pdev); + +	i2c_del_adapter(&id->adap); +	clk_notifier_unregister(id->clk, &id->clk_rate_change_nb); +	clk_disable_unprepare(id->clk); + +	return 0; +} + +static const struct of_device_id cdns_i2c_of_match[] = { +	{ .compatible = "cdns,i2c-r1p10", }, +	{ /* end of table */ } +}; +MODULE_DEVICE_TABLE(of, cdns_i2c_of_match); + +static struct platform_driver cdns_i2c_drv = { +	.driver = { +		.name  = DRIVER_NAME, +		.owner = THIS_MODULE, +		.of_match_table = cdns_i2c_of_match, +		.pm = &cdns_i2c_dev_pm_ops, +	}, +	.probe  = cdns_i2c_probe, +	.remove = cdns_i2c_remove, +}; + +module_platform_driver(cdns_i2c_drv); + +MODULE_AUTHOR("Xilinx Inc."); +MODULE_DESCRIPTION("Cadence I2C bus driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-cbus-gpio.c b/drivers/i2c/busses/i2c-cbus-gpio.c index 2d46f13adfd..bdf040fd867 100644 --- a/drivers/i2c/busses/i2c-cbus-gpio.c +++ b/drivers/i2c/busses/i2c-cbus-gpio.c @@ -19,7 +19,6 @@  #include <linux/io.h>  #include <linux/i2c.h>  #include <linux/gpio.h> -#include <linux/init.h>  #include <linux/slab.h>  #include <linux/delay.h>  #include <linux/errno.h> @@ -246,6 +245,7 @@ static int cbus_i2c_probe(struct platform_device *pdev)  	adapter->owner		= THIS_MODULE;  	adapter->class		= I2C_CLASS_HWMON;  	adapter->dev.parent	= &pdev->dev; +	adapter->dev.of_node	= pdev->dev.of_node;  	adapter->nr		= pdev->id;  	adapter->timeout	= HZ;  	adapter->algo		= &cbus_i2c_algo; @@ -289,6 +289,7 @@ static struct platform_driver cbus_i2c_driver = {  	.driver	= {  		.owner	= THIS_MODULE,  		.name	= "i2c-cbus-gpio", +		.of_match_table = of_match_ptr(i2c_cbus_dt_ids),  	},  };  module_platform_driver(cbus_i2c_driver); diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index b2b8aa9adc0..f3b89a4698b 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -33,14 +33,15 @@  #include <linux/module.h>  #include <linux/delay.h>  #include <linux/slab.h> -#include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/errno.h>  #include <linux/stddef.h>  #include <linux/i2c.h>  #include <linux/io.h>  #include <linux/dma-mapping.h> +#include <linux/of_address.h>  #include <linux/of_device.h> +#include <linux/of_irq.h>  #include <linux/of_platform.h>  #include <sysdev/fsl_soc.h>  #include <asm/cpm.h> @@ -447,7 +448,7 @@ static int cpm_i2c_setup(struct cpm_i2c *cpm)  	init_waitqueue_head(&cpm->i2c_wait); -	cpm->irq = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); +	cpm->irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);  	if (!cpm->irq)  		return -EINVAL; diff --git a/drivers/i2c/busses/i2c-cros-ec-tunnel.c b/drivers/i2c/busses/i2c-cros-ec-tunnel.c new file mode 100644 index 00000000000..8e7a71487bb --- /dev/null +++ b/drivers/i2c/busses/i2c-cros-ec-tunnel.c @@ -0,0 +1,318 @@ +/* + *  Copyright (C) 2013 Google, Inc + * + *  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. + * + * Expose an I2C passthrough to the ChromeOS EC. + */ + +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/mfd/cros_ec.h> +#include <linux/mfd/cros_ec_commands.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +/** + * struct ec_i2c_device - Driver data for I2C tunnel + * + * @dev: Device node + * @adap: I2C adapter + * @ec: Pointer to EC device + * @remote_bus: The EC bus number we tunnel to on the other side. + * @request_buf: Buffer for transmitting data; we expect most transfers to fit. + * @response_buf: Buffer for receiving data; we expect most transfers to fit. + */ + +struct ec_i2c_device { +	struct device *dev; +	struct i2c_adapter adap; +	struct cros_ec_device *ec; + +	u16 remote_bus; + +	u8 request_buf[256]; +	u8 response_buf[256]; +}; + +/** + * ec_i2c_count_message - Count bytes needed for ec_i2c_construct_message + * + * @i2c_msgs: The i2c messages to read + * @num: The number of i2c messages. + * + * Returns the number of bytes the messages will take up. + */ +static int ec_i2c_count_message(const struct i2c_msg i2c_msgs[], int num) +{ +	int i; +	int size; + +	size = sizeof(struct ec_params_i2c_passthru); +	size += num * sizeof(struct ec_params_i2c_passthru_msg); +	for (i = 0; i < num; i++) +		if (!(i2c_msgs[i].flags & I2C_M_RD)) +			size += i2c_msgs[i].len; + +	return size; +} + +/** + * ec_i2c_construct_message - construct a message to go to the EC + * + * This function effectively stuffs the standard i2c_msg format of Linux into + * a format that the EC understands. + * + * @buf: The buffer to fill.  We assume that the buffer is big enough. + * @i2c_msgs: The i2c messages to read. + * @num: The number of i2c messages. + * @bus_num: The remote bus number we want to talk to. + * + * Returns 0 or a negative error number. + */ +static int ec_i2c_construct_message(u8 *buf, const struct i2c_msg i2c_msgs[], +				    int num, u16 bus_num) +{ +	struct ec_params_i2c_passthru *params; +	u8 *out_data; +	int i; + +	out_data = buf + sizeof(struct ec_params_i2c_passthru) + +		   num * sizeof(struct ec_params_i2c_passthru_msg); + +	params = (struct ec_params_i2c_passthru *)buf; +	params->port = bus_num; +	params->num_msgs = num; +	for (i = 0; i < num; i++) { +		const struct i2c_msg *i2c_msg = &i2c_msgs[i]; +		struct ec_params_i2c_passthru_msg *msg = ¶ms->msg[i]; + +		msg->len = i2c_msg->len; +		msg->addr_flags = i2c_msg->addr; + +		if (i2c_msg->flags & I2C_M_TEN) +			msg->addr_flags |= EC_I2C_FLAG_10BIT; + +		if (i2c_msg->flags & I2C_M_RD) { +			msg->addr_flags |= EC_I2C_FLAG_READ; +		} else { +			memcpy(out_data, i2c_msg->buf, msg->len); +			out_data += msg->len; +		} +	} + +	return 0; +} + +/** + * ec_i2c_count_response - Count bytes needed for ec_i2c_parse_response + * + * @i2c_msgs: The i2c messages to to fill up. + * @num: The number of i2c messages expected. + * + * Returns the number of response bytes expeced. + */ +static int ec_i2c_count_response(struct i2c_msg i2c_msgs[], int num) +{ +	int size; +	int i; + +	size = sizeof(struct ec_response_i2c_passthru); +	for (i = 0; i < num; i++) +		if (i2c_msgs[i].flags & I2C_M_RD) +			size += i2c_msgs[i].len; + +	return size; +} + +/** + * ec_i2c_parse_response - Parse a response from the EC + * + * We'll take the EC's response and copy it back into msgs. + * + * @buf: The buffer to parse. + * @i2c_msgs: The i2c messages to to fill up. + * @num: The number of i2c messages; will be modified to include the actual + *	 number received. + * + * Returns 0 or a negative error number. + */ +static int ec_i2c_parse_response(const u8 *buf, struct i2c_msg i2c_msgs[], +				 int *num) +{ +	const struct ec_response_i2c_passthru *resp; +	const u8 *in_data; +	int i; + +	in_data = buf + sizeof(struct ec_response_i2c_passthru); + +	resp = (const struct ec_response_i2c_passthru *)buf; +	if (resp->i2c_status & EC_I2C_STATUS_TIMEOUT) +		return -ETIMEDOUT; +	else if (resp->i2c_status & EC_I2C_STATUS_ERROR) +		return -EREMOTEIO; + +	/* Other side could send us back fewer messages, but not more */ +	if (resp->num_msgs > *num) +		return -EPROTO; +	*num = resp->num_msgs; + +	for (i = 0; i < *num; i++) { +		struct i2c_msg *i2c_msg = &i2c_msgs[i]; + +		if (i2c_msgs[i].flags & I2C_M_RD) { +			memcpy(i2c_msg->buf, in_data, i2c_msg->len); +			in_data += i2c_msg->len; +		} +	} + +	return 0; +} + +static int ec_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg i2c_msgs[], +		       int num) +{ +	struct ec_i2c_device *bus = adap->algo_data; +	struct device *dev = bus->dev; +	const u16 bus_num = bus->remote_bus; +	int request_len; +	int response_len; +	u8 *request = NULL; +	u8 *response = NULL; +	int result; + +	request_len = ec_i2c_count_message(i2c_msgs, num); +	if (request_len < 0) { +		dev_warn(dev, "Error constructing message %d\n", request_len); +		result = request_len; +		goto exit; +	} +	response_len = ec_i2c_count_response(i2c_msgs, num); +	if (response_len < 0) { +		/* Unexpected; no errors should come when NULL response */ +		dev_warn(dev, "Error preparing response %d\n", response_len); +		result = response_len; +		goto exit; +	} + +	if (request_len <= ARRAY_SIZE(bus->request_buf)) { +		request = bus->request_buf; +	} else { +		request = kzalloc(request_len, GFP_KERNEL); +		if (request == NULL) { +			result = -ENOMEM; +			goto exit; +		} +	} +	if (response_len <= ARRAY_SIZE(bus->response_buf)) { +		response = bus->response_buf; +	} else { +		response = kzalloc(response_len, GFP_KERNEL); +		if (response == NULL) { +			result = -ENOMEM; +			goto exit; +		} +	} + +	ec_i2c_construct_message(request, i2c_msgs, num, bus_num); +	result = bus->ec->command_sendrecv(bus->ec, EC_CMD_I2C_PASSTHRU, +					   request, request_len, +					   response, response_len); +	if (result) +		goto exit; + +	result = ec_i2c_parse_response(response, i2c_msgs, &num); +	if (result < 0) +		goto exit; + +	/* Indicate success by saying how many messages were sent */ +	result = num; +exit: +	if (request != bus->request_buf) +		kfree(request); +	if (response != bus->response_buf) +		kfree(response); + +	return result; +} + +static u32 ec_i2c_functionality(struct i2c_adapter *adap) +{ +	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm ec_i2c_algorithm = { +	.master_xfer	= ec_i2c_xfer, +	.functionality	= ec_i2c_functionality, +}; + +static int ec_i2c_probe(struct platform_device *pdev) +{ +	struct device_node *np = pdev->dev.of_node; +	struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); +	struct device *dev = &pdev->dev; +	struct ec_i2c_device *bus = NULL; +	u32 remote_bus; +	int err; + +	if (!ec->command_sendrecv) { +		dev_err(dev, "Missing sendrecv\n"); +		return -EINVAL; +	} + +	bus = devm_kzalloc(dev, sizeof(*bus), GFP_KERNEL); +	if (bus == NULL) +		return -ENOMEM; + +	err = of_property_read_u32(np, "google,remote-bus", &remote_bus); +	if (err) { +		dev_err(dev, "Couldn't read remote-bus property\n"); +		return err; +	} +	bus->remote_bus = remote_bus; + +	bus->ec = ec; +	bus->dev = dev; + +	bus->adap.owner = THIS_MODULE; +	strlcpy(bus->adap.name, "cros-ec-i2c-tunnel", sizeof(bus->adap.name)); +	bus->adap.algo = &ec_i2c_algorithm; +	bus->adap.algo_data = bus; +	bus->adap.dev.parent = &pdev->dev; +	bus->adap.dev.of_node = np; + +	err = i2c_add_adapter(&bus->adap); +	if (err) { +		dev_err(dev, "cannot register i2c adapter\n"); +		return err; +	} +	platform_set_drvdata(pdev, bus); + +	return err; +} + +static int ec_i2c_remove(struct platform_device *dev) +{ +	struct ec_i2c_device *bus = platform_get_drvdata(dev); + +	i2c_del_adapter(&bus->adap); + +	return 0; +} + +static struct platform_driver ec_i2c_tunnel_driver = { +	.probe = ec_i2c_probe, +	.remove = ec_i2c_remove, +	.driver = { +		.name = "cros-ec-i2c-tunnel", +	}, +}; + +module_platform_driver(ec_i2c_tunnel_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("EC I2C tunnel driver"); +MODULE_ALIAS("platform:cros-ec-i2c-tunnel"); diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 132369fad4e..389bc68c55a 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -125,12 +125,12 @@ static struct davinci_i2c_platform_data davinci_i2c_platform_data_default = {  static inline void davinci_i2c_write_reg(struct davinci_i2c_dev *i2c_dev,  					 int reg, u16 val)  { -	__raw_writew(val, i2c_dev->base + reg); +	writew_relaxed(val, i2c_dev->base + reg);  }  static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)  { -	return __raw_readw(i2c_dev->base + reg); +	return readw_relaxed(i2c_dev->base + reg);  }  /* Generate a pulse on the i2c clock pin. */ @@ -323,7 +323,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)  	davinci_i2c_write_reg(dev, DAVINCI_I2C_CNT_REG, dev->buf_len); -	INIT_COMPLETION(dev->cmd_complete); +	reinit_completion(&dev->cmd_complete);  	dev->cmd_err = 0;  	/* Take I2C out of reset and configure it as master */ @@ -712,7 +712,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)  	adap = &dev->adapter;  	i2c_set_adapdata(adap, dev);  	adap->owner = THIS_MODULE; -	adap->class = I2C_CLASS_HWMON; +	adap->class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED;  	strlcpy(adap->name, "DaVinci I2C adapter", sizeof(adap->name));  	adap->algo = &i2c_davinci_algo;  	adap->dev.parent = &pdev->dev; @@ -795,7 +795,7 @@ static struct platform_driver davinci_i2c_driver = {  		.name	= "i2c_davinci",  		.owner	= THIS_MODULE,  		.pm	= davinci_i2c_pm_ops, -		.of_match_table = of_match_ptr(davinci_i2c_of_match), +		.of_match_table = davinci_i2c_of_match,  	},  }; diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 5888feef1ac..3c20e4bd6dd 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -26,7 +26,6 @@   *   */  #include <linux/export.h> -#include <linux/clk.h>  #include <linux/errno.h>  #include <linux/err.h>  #include <linux/i2c.h> @@ -219,7 +218,7 @@ i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)  		 *  		 * If your hardware is free from tHD;STA issue, try this one.  		 */ -		return (ic_clk * tSYMBOL + 5000) / 10000 - 8 + offset; +		return (ic_clk * tSYMBOL + 500000) / 1000000 - 8 + offset;  	else  		/*  		 * Conditional expression: @@ -235,7 +234,8 @@ i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)  		 * The reason why we need to take into account "tf" here,  		 * is the same as described in i2c_dw_scl_lcnt().  		 */ -		return (ic_clk * (tSYMBOL + tf) + 5000) / 10000 - 3 + offset; +		return (ic_clk * (tSYMBOL + tf) + 500000) / 1000000 +			- 3 + offset;  }  static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) @@ -251,7 +251,7 @@ static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)  	 * account the fall time of SCL signal (tf).  Default tf value  	 * should be 0.3 us, for safety.  	 */ -	return ((ic_clk * (tLOW + tf) + 5000) / 10000) - 1 + offset; +	return ((ic_clk * (tLOW + tf) + 500000) / 1000000) - 1 + offset;  }  static void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable) @@ -288,6 +288,7 @@ int i2c_dw_init(struct dw_i2c_dev *dev)  	u32 input_clock_khz;  	u32 hcnt, lcnt;  	u32 reg; +	u32 sda_falling_time, scl_falling_time;  	input_clock_khz = dev->get_clk_rate_khz(dev); @@ -309,15 +310,18 @@ int i2c_dw_init(struct dw_i2c_dev *dev)  	/* set standard and fast speed deviders for high/low periods */ +	sda_falling_time = dev->sda_falling_time ?: 300; /* ns */ +	scl_falling_time = dev->scl_falling_time ?: 300; /* ns */ +  	/* Standard-mode */  	hcnt = i2c_dw_scl_hcnt(input_clock_khz, -				40,	/* tHD;STA = tHIGH = 4.0 us */ -				3,	/* tf = 0.3 us */ +				4000,	/* tHD;STA = tHIGH = 4.0 us */ +				sda_falling_time,  				0,	/* 0: DW default, 1: Ideal */  				0);	/* No offset */  	lcnt = i2c_dw_scl_lcnt(input_clock_khz, -				47,	/* tLOW = 4.7 us */ -				3,	/* tf = 0.3 us */ +				4700,	/* tLOW = 4.7 us */ +				scl_falling_time,  				0);	/* No offset */  	/* Allow platforms to specify the ideal HCNT and LCNT values */ @@ -331,13 +335,13 @@ int i2c_dw_init(struct dw_i2c_dev *dev)  	/* Fast-mode */  	hcnt = i2c_dw_scl_hcnt(input_clock_khz, -				6,	/* tHD;STA = tHIGH = 0.6 us */ -				3,	/* tf = 0.3 us */ +				600,	/* tHD;STA = tHIGH = 0.6 us */ +				sda_falling_time,  				0,	/* 0: DW default, 1: Ideal */  				0);	/* No offset */  	lcnt = i2c_dw_scl_lcnt(input_clock_khz, -				13,	/* tLOW = 1.3 us */ -				3,	/* tf = 0.3 us */ +				1300,	/* tLOW = 1.3 us */ +				scl_falling_time,  				0);	/* No offset */  	if (dev->fs_hcnt && dev->fs_lcnt) { @@ -418,6 +422,9 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)  	 */  	dw_writel(dev, msgs[dev->msg_write_idx].addr | ic_tar, DW_IC_TAR); +	/* enforce disabled interrupts (due to HW issues) */ +	i2c_dw_disable_int(dev); +  	/* Enable the adapter */  	__i2c_dw_enable(dev, true); @@ -613,7 +620,7 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)  	mutex_lock(&dev->lock);  	pm_runtime_get_sync(dev->dev); -	INIT_COMPLETION(dev->cmd_complete); +	reinit_completion(&dev->cmd_complete);  	dev->msgs = msgs;  	dev->msgs_num = num;  	dev->cmd_err = 0; diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index e8a756537ed..d66b6cbc9ed 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -99,6 +99,8 @@ struct dw_i2c_dev {  	unsigned int		rx_fifo_depth;  	int			rx_outstanding;  	u32			sda_hold_time; +	u32			sda_falling_time; +	u32			scl_falling_time;  	u16			ss_hcnt;  	u16			ss_lcnt;  	u16			fs_hcnt; diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c index f6ed06c966e..3356f7ab9f7 100644 --- a/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -54,6 +54,17 @@ enum dw_pci_ctl_id_t {  	medfield_3,  	medfield_4,  	medfield_5, + +	baytrail, +	haswell, +}; + +struct dw_scl_sda_cfg { +	u32 ss_hcnt; +	u32 fs_hcnt; +	u32 ss_lcnt; +	u32 fs_lcnt; +	u32 sda_hold;  };  struct dw_pci_controller { @@ -62,12 +73,38 @@ struct dw_pci_controller {  	u32 tx_fifo_depth;  	u32 rx_fifo_depth;  	u32 clk_khz; +	u32 functionality; +	struct dw_scl_sda_cfg *scl_sda_cfg;  };  #define INTEL_MID_STD_CFG  (DW_IC_CON_MASTER |			\  				DW_IC_CON_SLAVE_DISABLE |	\  				DW_IC_CON_RESTART_EN) +#define DW_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C |			\ +					I2C_FUNC_SMBUS_BYTE |		\ +					I2C_FUNC_SMBUS_BYTE_DATA |	\ +					I2C_FUNC_SMBUS_WORD_DATA |	\ +					I2C_FUNC_SMBUS_I2C_BLOCK) + +/* BayTrail HCNT/LCNT/SDA hold time */ +static struct dw_scl_sda_cfg byt_config = { +	.ss_hcnt = 0x200, +	.fs_hcnt = 0x55, +	.ss_lcnt = 0x200, +	.fs_lcnt = 0x99, +	.sda_hold = 0x6, +}; + +/* Haswell HCNT/LCNT/SDA hold time */ +static struct dw_scl_sda_cfg hsw_config = { +	.ss_hcnt = 0x01b0, +	.fs_hcnt = 0x48, +	.ss_lcnt = 0x01fb, +	.fs_lcnt = 0xa0, +	.sda_hold = 0x9, +}; +  static struct  dw_pci_controller  dw_pci_controllers[] = {  	[moorestown_0] = {  		.bus_num     = 0, @@ -132,75 +169,49 @@ static struct  dw_pci_controller  dw_pci_controllers[] = {  		.rx_fifo_depth = 32,  		.clk_khz      = 25000,  	}, +	[baytrail] = { +		.bus_num = -1, +		.bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST, +		.tx_fifo_depth = 32, +		.rx_fifo_depth = 32, +		.clk_khz = 100000, +		.functionality = I2C_FUNC_10BIT_ADDR, +		.scl_sda_cfg = &byt_config, +	}, +	[haswell] = { +		.bus_num = -1, +		.bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST, +		.tx_fifo_depth = 32, +		.rx_fifo_depth = 32, +		.clk_khz = 100000, +		.functionality = I2C_FUNC_10BIT_ADDR, +		.scl_sda_cfg = &hsw_config, +	},  };  static struct i2c_algorithm i2c_dw_algo = {  	.master_xfer	= i2c_dw_xfer,  	.functionality	= i2c_dw_func,  }; +#ifdef CONFIG_PM  static int i2c_dw_pci_suspend(struct device *dev)  {  	struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); -	struct dw_i2c_dev *i2c = pci_get_drvdata(pdev); -	int err; - - -	i2c_dw_disable(i2c); - -	err = pci_save_state(pdev); -	if (err) { -		dev_err(&pdev->dev, "pci_save_state failed\n"); -		return err; -	} - -	err = pci_set_power_state(pdev, PCI_D3hot); -	if (err) { -		dev_err(&pdev->dev, "pci_set_power_state failed\n"); -		return err; -	} +	i2c_dw_disable(pci_get_drvdata(pdev));  	return 0;  }  static int i2c_dw_pci_resume(struct device *dev)  {  	struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); -	struct dw_i2c_dev *i2c = pci_get_drvdata(pdev); -	int err; -	u32 enabled; - -	enabled = i2c_dw_is_enabled(i2c); -	if (enabled) -		return 0; - -	err = pci_set_power_state(pdev, PCI_D0); -	if (err) { -		dev_err(&pdev->dev, "pci_set_power_state() failed\n"); -		return err; -	} - -	pci_restore_state(pdev); -	i2c_dw_init(i2c); -	return 0; +	return i2c_dw_init(pci_get_drvdata(pdev));  } +#endif -static int i2c_dw_pci_runtime_idle(struct device *dev) -{ -	int err = pm_schedule_suspend(dev, 500); -	dev_dbg(dev, "runtime_idle called\n"); - -	if (err != 0) -		return 0; -	return -EBUSY; -} - -static const struct dev_pm_ops i2c_dw_pm_ops = { -	.resume         = i2c_dw_pci_resume, -	.suspend        = i2c_dw_pci_suspend, -	SET_RUNTIME_PM_OPS(i2c_dw_pci_suspend, i2c_dw_pci_resume, -			   i2c_dw_pci_runtime_idle) -}; +static UNIVERSAL_DEV_PM_OPS(i2c_dw_pm_ops, i2c_dw_pci_suspend, +			    i2c_dw_pci_resume, NULL);  static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)  { @@ -214,6 +225,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,  	struct i2c_adapter *adap;  	int r;  	struct  dw_pci_controller *controller; +	struct dw_scl_sda_cfg *cfg;  	if (id->driver_data >= ARRAY_SIZE(dw_pci_controllers)) {  		dev_err(&pdev->dev, "%s: invalid driver data %ld\n", __func__, @@ -247,13 +259,18 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,  	dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;  	dev->base = pcim_iomap_table(pdev)[0];  	dev->dev = &pdev->dev; -	dev->functionality = -		I2C_FUNC_I2C | -		I2C_FUNC_SMBUS_BYTE | -		I2C_FUNC_SMBUS_BYTE_DATA | -		I2C_FUNC_SMBUS_WORD_DATA | -		I2C_FUNC_SMBUS_I2C_BLOCK; +	dev->functionality = controller->functionality | +				DW_DEFAULT_FUNCTIONALITY; +  	dev->master_cfg =  controller->bus_cfg; +	if (controller->scl_sda_cfg) { +		cfg = controller->scl_sda_cfg; +		dev->ss_hcnt = cfg->ss_hcnt; +		dev->fs_hcnt = cfg->fs_hcnt; +		dev->ss_lcnt = cfg->ss_lcnt; +		dev->fs_lcnt = cfg->fs_lcnt; +		dev->sda_hold_time = cfg->sda_hold; +	}  	pci_set_drvdata(pdev, dev); @@ -270,8 +287,8 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,  	adap->algo = &i2c_dw_algo;  	adap->dev.parent = &pdev->dev;  	adap->nr = controller->bus_num; -	snprintf(adap->name, sizeof(adap->name), "i2c-designware-pci-%d", -		adap->nr); + +	snprintf(adap->name, sizeof(adap->name), "i2c-designware-pci");  	r = devm_request_irq(&pdev->dev, pdev->irq, i2c_dw_isr, IRQF_SHARED,  			adap->name, dev); @@ -290,6 +307,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,  	pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);  	pm_runtime_use_autosuspend(&pdev->dev); +	pm_runtime_put_autosuspend(&pdev->dev);  	pm_runtime_allow(&pdev->dev);  	return 0; @@ -309,7 +327,7 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev)  /* work with hotplug and coldplug */  MODULE_ALIAS("i2c_designware-pci"); -static DEFINE_PCI_DEVICE_TABLE(i2_designware_pci_ids) = { +static const struct pci_device_id i2_designware_pci_ids[] = {  	/* Moorestown */  	{ PCI_VDEVICE(INTEL, 0x0802), moorestown_0 },  	{ PCI_VDEVICE(INTEL, 0x0803), moorestown_1 }, @@ -321,6 +339,17 @@ static DEFINE_PCI_DEVICE_TABLE(i2_designware_pci_ids) = {  	{ PCI_VDEVICE(INTEL, 0x082C), medfield_0 },  	{ PCI_VDEVICE(INTEL, 0x082D), medfield_1 },  	{ PCI_VDEVICE(INTEL, 0x082E), medfield_2 }, +	/* Baytrail */ +	{ PCI_VDEVICE(INTEL, 0x0F41), baytrail }, +	{ PCI_VDEVICE(INTEL, 0x0F42), baytrail }, +	{ PCI_VDEVICE(INTEL, 0x0F43), baytrail }, +	{ PCI_VDEVICE(INTEL, 0x0F44), baytrail }, +	{ PCI_VDEVICE(INTEL, 0x0F45), baytrail }, +	{ PCI_VDEVICE(INTEL, 0x0F46), baytrail }, +	{ PCI_VDEVICE(INTEL, 0x0F47), baytrail }, +	/* Haswell */ +	{ PCI_VDEVICE(INTEL, 0x9c61), haswell }, +	{ PCI_VDEVICE(INTEL, 0x9c62), haswell },  	{ 0,}  };  MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids); diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 4c1b60539a2..402ec3970fe 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -103,6 +103,8 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)  static const struct acpi_device_id dw_i2c_acpi_match[] = {  	{ "INT33C2", 0 },  	{ "INT33C3", 0 }, +	{ "INT3432", 0 }, +	{ "INT3433", 0 },  	{ "80860F41", 0 },  	{ }  }; @@ -157,6 +159,13 @@ static int dw_i2c_probe(struct platform_device *pdev)  					"i2c-sda-hold-time-ns", &ht);  		dev->sda_hold_time = div_u64((u64)ic_clk * ht + 500000,  					     1000000); + +		of_property_read_u32(pdev->dev.of_node, +				     "i2c-sda-falling-time-ns", +				     &dev->sda_falling_time); +		of_property_read_u32(pdev->dev.of_node, +				     "i2c-scl-falling-time-ns", +				     &dev->scl_falling_time);  	}  	dev->functionality = @@ -193,7 +202,7 @@ static int dw_i2c_probe(struct platform_device *pdev)  	adap = &dev->adapter;  	i2c_set_adapdata(adap, dev);  	adap->owner = THIS_MODULE; -	adap->class = I2C_CLASS_HWMON; +	adap->class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED;  	strlcpy(adap->name, "Synopsys DesignWare I2C adapter",  			sizeof(adap->name));  	adap->algo = &i2c_dw_algo; @@ -238,12 +247,13 @@ static const struct of_device_id dw_i2c_of_match[] = {  MODULE_DEVICE_TABLE(of, dw_i2c_of_match);  #endif -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM  static int dw_i2c_suspend(struct device *dev)  {  	struct platform_device *pdev = to_platform_device(dev);  	struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev); +	i2c_dw_disable(i_dev);  	clk_disable_unprepare(i_dev->clk);  	return 0; @@ -259,30 +269,29 @@ static int dw_i2c_resume(struct device *dev)  	return 0;  } - -static SIMPLE_DEV_PM_OPS(dw_i2c_dev_pm_ops, dw_i2c_suspend, dw_i2c_resume); -#define DW_I2C_DEV_PM_OPS	(&dw_i2c_dev_pm_ops) -#else -#define DW_I2C_DEV_PM_OPS	NULL  #endif +static UNIVERSAL_DEV_PM_OPS(dw_i2c_dev_pm_ops, dw_i2c_suspend, +			    dw_i2c_resume, NULL); +  /* work with hotplug and coldplug */  MODULE_ALIAS("platform:i2c_designware");  static struct platform_driver dw_i2c_driver = { -	.remove		= dw_i2c_remove, +	.probe = dw_i2c_probe, +	.remove = dw_i2c_remove,  	.driver		= {  		.name	= "i2c_designware",  		.owner	= THIS_MODULE,  		.of_match_table = of_match_ptr(dw_i2c_of_match),  		.acpi_match_table = ACPI_PTR(dw_i2c_acpi_match), -		.pm	= DW_I2C_DEV_PM_OPS, +		.pm	= &dw_i2c_dev_pm_ops,  	},  };  static int __init dw_i2c_init_driver(void)  { -	return platform_driver_probe(&dw_i2c_driver, dw_i2c_probe); +	return platform_driver_register(&dw_i2c_driver);  }  subsys_initcall(dw_i2c_init_driver); diff --git a/drivers/i2c/busses/i2c-diolan-u2c.c b/drivers/i2c/busses/i2c-diolan-u2c.c index dae3ddfe761..b19a310bf9b 100644 --- a/drivers/i2c/busses/i2c-diolan-u2c.c +++ b/drivers/i2c/busses/i2c-diolan-u2c.c @@ -25,8 +25,6 @@  #define USB_VENDOR_ID_DIOLAN		0x0abf  #define USB_DEVICE_ID_DIOLAN_U2C	0x3370 -#define DIOLAN_OUT_EP		0x02 -#define DIOLAN_IN_EP		0x84  /* commands via USB, must match command ids in the firmware */  #define CMD_I2C_READ		0x01 @@ -84,6 +82,7 @@  struct i2c_diolan_u2c {  	u8 obuffer[DIOLAN_OUTBUF_LEN];	/* output buffer */  	u8 ibuffer[DIOLAN_INBUF_LEN];	/* input buffer */ +	int ep_in, ep_out;              /* Endpoints    */  	struct usb_device *usb_dev;	/* the usb device for this device */  	struct usb_interface *interface;/* the interface for this device */  	struct i2c_adapter adapter;	/* i2c related things */ @@ -109,7 +108,7 @@ static int diolan_usb_transfer(struct i2c_diolan_u2c *dev)  		return -EINVAL;  	ret = usb_bulk_msg(dev->usb_dev, -			   usb_sndbulkpipe(dev->usb_dev, DIOLAN_OUT_EP), +			   usb_sndbulkpipe(dev->usb_dev, dev->ep_out),  			   dev->obuffer, dev->olen, &actual,  			   DIOLAN_USB_TIMEOUT);  	if (!ret) { @@ -118,7 +117,7 @@ static int diolan_usb_transfer(struct i2c_diolan_u2c *dev)  			tmpret = usb_bulk_msg(dev->usb_dev,  					      usb_rcvbulkpipe(dev->usb_dev, -							      DIOLAN_IN_EP), +							      dev->ep_in),  					      dev->ibuffer,  					      sizeof(dev->ibuffer), &actual,  					      DIOLAN_USB_TIMEOUT); @@ -210,7 +209,7 @@ static void diolan_flush_input(struct i2c_diolan_u2c *dev)  		int ret;  		ret = usb_bulk_msg(dev->usb_dev, -				   usb_rcvbulkpipe(dev->usb_dev, DIOLAN_IN_EP), +				   usb_rcvbulkpipe(dev->usb_dev, dev->ep_in),  				   dev->ibuffer, sizeof(dev->ibuffer), &actual,  				   DIOLAN_USB_TIMEOUT);  		if (ret < 0 || actual == 0) @@ -445,16 +444,22 @@ static void diolan_u2c_free(struct i2c_diolan_u2c *dev)  static int diolan_u2c_probe(struct usb_interface *interface,  			    const struct usb_device_id *id)  { +	struct usb_host_interface *hostif = interface->cur_altsetting;  	struct i2c_diolan_u2c *dev;  	int ret; +	if (hostif->desc.bInterfaceNumber != 0 +	    || hostif->desc.bNumEndpoints < 2) +		return -ENODEV; +  	/* allocate memory for our device state and initialize it */  	dev = kzalloc(sizeof(*dev), GFP_KERNEL);  	if (dev == NULL) { -		dev_err(&interface->dev, "no memory for device state\n");  		ret = -ENOMEM;  		goto error;  	} +	dev->ep_out = hostif->endpoint[0].desc.bEndpointAddress; +	dev->ep_in = hostif->endpoint[1].desc.bEndpointAddress;  	dev->usb_dev = usb_get_dev(interface_to_usbdev(interface));  	dev->interface = interface; diff --git a/drivers/i2c/busses/i2c-efm32.c b/drivers/i2c/busses/i2c-efm32.c new file mode 100644 index 00000000000..f7eccd682de --- /dev/null +++ b/drivers/i2c/busses/i2c-efm32.c @@ -0,0 +1,479 @@ +/* + * Copyright (C) 2014 Uwe Kleine-Koenig for Pengutronix + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + */ +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/err.h> +#include <linux/clk.h> + +#define DRIVER_NAME "efm32-i2c" + +#define MASK_VAL(mask, val)		((val << __ffs(mask)) & mask) + +#define REG_CTRL		0x00 +#define REG_CTRL_EN			0x00001 +#define REG_CTRL_SLAVE			0x00002 +#define REG_CTRL_AUTOACK		0x00004 +#define REG_CTRL_AUTOSE			0x00008 +#define REG_CTRL_AUTOSN			0x00010 +#define REG_CTRL_ARBDIS			0x00020 +#define REG_CTRL_GCAMEN			0x00040 +#define REG_CTRL_CLHR__MASK		0x00300 +#define REG_CTRL_BITO__MASK		0x03000 +#define REG_CTRL_BITO_OFF		0x00000 +#define REG_CTRL_BITO_40PCC		0x01000 +#define REG_CTRL_BITO_80PCC		0x02000 +#define REG_CTRL_BITO_160PCC		0x03000 +#define REG_CTRL_GIBITO			0x08000 +#define REG_CTRL_CLTO__MASK		0x70000 +#define REG_CTRL_CLTO_OFF		0x00000 + +#define REG_CMD			0x04 +#define REG_CMD_START			0x00001 +#define REG_CMD_STOP			0x00002 +#define REG_CMD_ACK			0x00004 +#define REG_CMD_NACK			0x00008 +#define REG_CMD_CONT			0x00010 +#define REG_CMD_ABORT			0x00020 +#define REG_CMD_CLEARTX			0x00040 +#define REG_CMD_CLEARPC			0x00080 + +#define REG_STATE		0x08 +#define REG_STATE_BUSY			0x00001 +#define REG_STATE_MASTER		0x00002 +#define REG_STATE_TRANSMITTER		0x00004 +#define REG_STATE_NACKED		0x00008 +#define REG_STATE_BUSHOLD		0x00010 +#define REG_STATE_STATE__MASK		0x000e0 +#define REG_STATE_STATE_IDLE		0x00000 +#define REG_STATE_STATE_WAIT		0x00020 +#define REG_STATE_STATE_START		0x00040 +#define REG_STATE_STATE_ADDR		0x00060 +#define REG_STATE_STATE_ADDRACK		0x00080 +#define REG_STATE_STATE_DATA		0x000a0 +#define REG_STATE_STATE_DATAACK		0x000c0 + +#define REG_STATUS		0x0c +#define REG_STATUS_PSTART		0x00001 +#define REG_STATUS_PSTOP		0x00002 +#define REG_STATUS_PACK			0x00004 +#define REG_STATUS_PNACK		0x00008 +#define REG_STATUS_PCONT		0x00010 +#define REG_STATUS_PABORT		0x00020 +#define REG_STATUS_TXC			0x00040 +#define REG_STATUS_TXBL			0x00080 +#define REG_STATUS_RXDATAV		0x00100 + +#define REG_CLKDIV		0x10 +#define REG_CLKDIV_DIV__MASK		0x001ff +#define REG_CLKDIV_DIV(div)		MASK_VAL(REG_CLKDIV_DIV__MASK, (div)) + +#define REG_SADDR		0x14 +#define REG_SADDRMASK		0x18 +#define REG_RXDATA		0x1c +#define REG_RXDATAP		0x20 +#define REG_TXDATA		0x24 +#define REG_IF			0x28 +#define REG_IF_START			0x00001 +#define REG_IF_RSTART			0x00002 +#define REG_IF_ADDR			0x00004 +#define REG_IF_TXC			0x00008 +#define REG_IF_TXBL			0x00010 +#define REG_IF_RXDATAV			0x00020 +#define REG_IF_ACK			0x00040 +#define REG_IF_NACK			0x00080 +#define REG_IF_MSTOP			0x00100 +#define REG_IF_ARBLOST			0x00200 +#define REG_IF_BUSERR			0x00400 +#define REG_IF_BUSHOLD			0x00800 +#define REG_IF_TXOF			0x01000 +#define REG_IF_RXUF			0x02000 +#define REG_IF_BITO			0x04000 +#define REG_IF_CLTO			0x08000 +#define REG_IF_SSTOP			0x10000 + +#define REG_IFS			0x2c +#define REG_IFC			0x30 +#define REG_IFC__MASK			0x1ffcf + +#define REG_IEN			0x34 + +#define REG_ROUTE		0x38 +#define REG_ROUTE_SDAPEN		0x00001 +#define REG_ROUTE_SCLPEN		0x00002 +#define REG_ROUTE_LOCATION__MASK	0x00700 +#define REG_ROUTE_LOCATION(n)		MASK_VAL(REG_ROUTE_LOCATION__MASK, (n)) + +struct efm32_i2c_ddata { +	struct i2c_adapter adapter; + +	struct clk *clk; +	void __iomem *base; +	unsigned int irq; +	u8 location; +	unsigned long frequency; + +	/* transfer data */ +	struct completion done; +	struct i2c_msg *msgs; +	size_t num_msgs; +	size_t current_word, current_msg; +	int retval; +}; + +static u32 efm32_i2c_read32(struct efm32_i2c_ddata *ddata, unsigned offset) +{ +	return readl(ddata->base + offset); +} + +static void efm32_i2c_write32(struct efm32_i2c_ddata *ddata, +		unsigned offset, u32 value) +{ +	writel(value, ddata->base + offset); +} + +static void efm32_i2c_send_next_msg(struct efm32_i2c_ddata *ddata) +{ +	struct i2c_msg *cur_msg = &ddata->msgs[ddata->current_msg]; + +	efm32_i2c_write32(ddata, REG_CMD, REG_CMD_START); +	efm32_i2c_write32(ddata, REG_TXDATA, cur_msg->addr << 1 | +			(cur_msg->flags & I2C_M_RD ? 1 : 0)); +} + +static void efm32_i2c_send_next_byte(struct efm32_i2c_ddata *ddata) +{ +	struct i2c_msg *cur_msg = &ddata->msgs[ddata->current_msg]; + +	if (ddata->current_word >= cur_msg->len) { +		/* cur_msg completely transferred */ +		ddata->current_word = 0; +		ddata->current_msg += 1; + +		if (ddata->current_msg >= ddata->num_msgs) { +			efm32_i2c_write32(ddata, REG_CMD, REG_CMD_STOP); +			complete(&ddata->done); +		} else { +			efm32_i2c_send_next_msg(ddata); +		} +	} else { +		efm32_i2c_write32(ddata, REG_TXDATA, +				cur_msg->buf[ddata->current_word++]); +	} +} + +static void efm32_i2c_recv_next_byte(struct efm32_i2c_ddata *ddata) +{ +	struct i2c_msg *cur_msg = &ddata->msgs[ddata->current_msg]; + +	cur_msg->buf[ddata->current_word] = efm32_i2c_read32(ddata, REG_RXDATA); +	ddata->current_word += 1; +	if (ddata->current_word >= cur_msg->len) { +		/* cur_msg completely transferred */ +		ddata->current_word = 0; +		ddata->current_msg += 1; + +		efm32_i2c_write32(ddata, REG_CMD, REG_CMD_NACK); + +		if (ddata->current_msg >= ddata->num_msgs) { +			efm32_i2c_write32(ddata, REG_CMD, REG_CMD_STOP); +			complete(&ddata->done); +		} else { +			efm32_i2c_send_next_msg(ddata); +		} +	} else { +		efm32_i2c_write32(ddata, REG_CMD, REG_CMD_ACK); +	} +} + +static irqreturn_t efm32_i2c_irq(int irq, void *dev_id) +{ +	struct efm32_i2c_ddata *ddata = dev_id; +	struct i2c_msg *cur_msg = &ddata->msgs[ddata->current_msg]; +	u32 irqflag = efm32_i2c_read32(ddata, REG_IF); +	u32 state = efm32_i2c_read32(ddata, REG_STATE); + +	efm32_i2c_write32(ddata, REG_IFC, irqflag & REG_IFC__MASK); + +	switch (state & REG_STATE_STATE__MASK) { +	case REG_STATE_STATE_IDLE: +		/* arbitration lost? */ +		ddata->retval = -EAGAIN; +		complete(&ddata->done); +		break; +	case REG_STATE_STATE_WAIT: +		/* +		 * huh, this shouldn't happen. +		 * Reset hardware state and get out +		 */ +		ddata->retval = -EIO; +		efm32_i2c_write32(ddata, REG_CMD, +				REG_CMD_STOP | REG_CMD_ABORT | +				REG_CMD_CLEARTX | REG_CMD_CLEARPC); +		complete(&ddata->done); +		break; +	case REG_STATE_STATE_START: +		/* "caller" is expected to send an address */ +		break; +	case REG_STATE_STATE_ADDR: +		/* wait for Ack or NAck of slave */ +		break; +	case REG_STATE_STATE_ADDRACK: +		if (state & REG_STATE_NACKED) { +			efm32_i2c_write32(ddata, REG_CMD, REG_CMD_STOP); +			ddata->retval = -ENXIO; +			complete(&ddata->done); +		} else if (cur_msg->flags & I2C_M_RD) { +			/* wait for slave to send first data byte */ +		} else { +			efm32_i2c_send_next_byte(ddata); +		} +		break; +	case REG_STATE_STATE_DATA: +		if (cur_msg->flags & I2C_M_RD) { +			efm32_i2c_recv_next_byte(ddata); +		} else { +			/* wait for Ack or Nack of slave */ +		} +		break; +	case REG_STATE_STATE_DATAACK: +		if (state & REG_STATE_NACKED) { +			efm32_i2c_write32(ddata, REG_CMD, REG_CMD_STOP); +			complete(&ddata->done); +		} else { +			efm32_i2c_send_next_byte(ddata); +		} +	} + +	return IRQ_HANDLED; +} + +static int efm32_i2c_master_xfer(struct i2c_adapter *adap, +		struct i2c_msg *msgs, int num) +{ +	struct efm32_i2c_ddata *ddata = i2c_get_adapdata(adap); +	int ret; + +	if (ddata->msgs) +		return -EBUSY; + +	ddata->msgs = msgs; +	ddata->num_msgs = num; +	ddata->current_word = 0; +	ddata->current_msg = 0; +	ddata->retval = -EIO; + +	reinit_completion(&ddata->done); + +	dev_dbg(&ddata->adapter.dev, "state: %08x, status: %08x\n", +			efm32_i2c_read32(ddata, REG_STATE), +			efm32_i2c_read32(ddata, REG_STATUS)); + +	efm32_i2c_send_next_msg(ddata); + +	wait_for_completion(&ddata->done); + +	if (ddata->current_msg >= ddata->num_msgs) +		ret = ddata->num_msgs; +	else +		ret = ddata->retval; + +	return ret; +} + +static u32 efm32_i2c_functionality(struct i2c_adapter *adap) +{ +	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm efm32_i2c_algo = { +	.master_xfer = efm32_i2c_master_xfer, +	.functionality = efm32_i2c_functionality, +}; + +static u32 efm32_i2c_get_configured_location(struct efm32_i2c_ddata *ddata) +{ +	u32 reg = efm32_i2c_read32(ddata, REG_ROUTE); + +	return (reg & REG_ROUTE_LOCATION__MASK) >> +		__ffs(REG_ROUTE_LOCATION__MASK); +} + +static int efm32_i2c_probe(struct platform_device *pdev) +{ +	struct efm32_i2c_ddata *ddata; +	struct resource *res; +	unsigned long rate; +	struct device_node *np = pdev->dev.of_node; +	u32 location, frequency; +	int ret; +	u32 clkdiv; + +	if (!np) +		return -EINVAL; + +	ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL); +	if (!ddata) +		return -ENOMEM; +	platform_set_drvdata(pdev, ddata); + +	init_completion(&ddata->done); +	strlcpy(ddata->adapter.name, pdev->name, sizeof(ddata->adapter.name)); +	ddata->adapter.owner = THIS_MODULE; +	ddata->adapter.algo = &efm32_i2c_algo; +	ddata->adapter.dev.parent = &pdev->dev; +	ddata->adapter.dev.of_node = pdev->dev.of_node; +	i2c_set_adapdata(&ddata->adapter, ddata); + +	ddata->clk = devm_clk_get(&pdev->dev, NULL); +	if (IS_ERR(ddata->clk)) { +		ret = PTR_ERR(ddata->clk); +		dev_err(&pdev->dev, "failed to get clock: %d\n", ret); +		return ret; +	} + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	if (!res) { +		dev_err(&pdev->dev, "failed to determine base address\n"); +		return -ENODEV; +	} + +	if (resource_size(res) < 0x42) { +		dev_err(&pdev->dev, "memory resource too small\n"); +		return -EINVAL; +	} + +	ddata->base = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(ddata->base)) +		return PTR_ERR(ddata->base); + +	ret = platform_get_irq(pdev, 0); +	if (ret <= 0) { +		dev_err(&pdev->dev, "failed to get irq (%d)\n", ret); +		if (!ret) +			ret = -EINVAL; +		return ret; +	} + +	ddata->irq = ret; + +	ret = clk_prepare_enable(ddata->clk); +	if (ret < 0) { +		dev_err(&pdev->dev, "failed to enable clock (%d)\n", ret); +		return ret; +	} + +	ret = of_property_read_u32(np, "efm32,location", &location); +	if (!ret) { +		dev_dbg(&pdev->dev, "using location %u\n", location); +	} else { +		/* default to location configured in hardware */ +		location = efm32_i2c_get_configured_location(ddata); + +		dev_info(&pdev->dev, "fall back to location %u\n", location); +	} + +	ddata->location = location; + +	ret = of_property_read_u32(np, "clock-frequency", &frequency); +	if (!ret) { +		dev_dbg(&pdev->dev, "using frequency %u\n", frequency); +	} else { +		frequency = 100000; +		dev_info(&pdev->dev, "defaulting to 100 kHz\n"); +	} +	ddata->frequency = frequency; + +	rate = clk_get_rate(ddata->clk); +	if (!rate) { +		dev_err(&pdev->dev, "there is no input clock available\n"); +		ret = -EINVAL; +		goto err_disable_clk; +	} +	clkdiv = DIV_ROUND_UP(rate, 8 * ddata->frequency) - 1; +	if (clkdiv >= 0x200) { +		dev_err(&pdev->dev, +				"input clock too fast (%lu) to divide down to bus freq (%lu)", +				rate, ddata->frequency); +		ret = -EINVAL; +		goto err_disable_clk; +	} + +	dev_dbg(&pdev->dev, "input clock = %lu, bus freq = %lu, clkdiv = %lu\n", +			rate, ddata->frequency, (unsigned long)clkdiv); +	efm32_i2c_write32(ddata, REG_CLKDIV, REG_CLKDIV_DIV(clkdiv)); + +	efm32_i2c_write32(ddata, REG_ROUTE, REG_ROUTE_SDAPEN | +			REG_ROUTE_SCLPEN | +			REG_ROUTE_LOCATION(ddata->location)); + +	efm32_i2c_write32(ddata, REG_CTRL, REG_CTRL_EN | +			REG_CTRL_BITO_160PCC | 0 * REG_CTRL_GIBITO); + +	efm32_i2c_write32(ddata, REG_IFC, REG_IFC__MASK); +	efm32_i2c_write32(ddata, REG_IEN, REG_IF_TXC | REG_IF_ACK | REG_IF_NACK +			| REG_IF_ARBLOST | REG_IF_BUSERR | REG_IF_RXDATAV); + +	/* to make bus idle */ +	efm32_i2c_write32(ddata, REG_CMD, REG_CMD_ABORT); + +	ret = request_irq(ddata->irq, efm32_i2c_irq, 0, DRIVER_NAME, ddata); +	if (ret < 0) { +		dev_err(&pdev->dev, "failed to request irq (%d)\n", ret); +		return ret; +	} + +	ret = i2c_add_adapter(&ddata->adapter); +	if (ret) { +		dev_err(&pdev->dev, "failed to add i2c adapter (%d)\n", ret); +		free_irq(ddata->irq, ddata); + +err_disable_clk: +		clk_disable_unprepare(ddata->clk); +	} +	return ret; +} + +static int efm32_i2c_remove(struct platform_device *pdev) +{ +	struct efm32_i2c_ddata *ddata = platform_get_drvdata(pdev); + +	i2c_del_adapter(&ddata->adapter); +	free_irq(ddata->irq, ddata); +	clk_disable_unprepare(ddata->clk); + +	return 0; +} + +static const struct of_device_id efm32_i2c_dt_ids[] = { +	{ +		.compatible = "energymicro,efm32-i2c", +	}, { +		/* sentinel */ +	} +}; +MODULE_DEVICE_TABLE(of, efm32_i2c_dt_ids); + +static struct platform_driver efm32_i2c_driver = { +	.probe = efm32_i2c_probe, +	.remove = efm32_i2c_remove, + +	.driver = { +		.name = DRIVER_NAME, +		.owner = THIS_MODULE, +		.of_match_table = efm32_i2c_dt_ids, +	}, +}; +module_platform_driver(efm32_i2c_driver); + +MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>"); +MODULE_DESCRIPTION("EFM32 i2c driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index 0f3752967c4..a44ea13d143 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c @@ -18,7 +18,6 @@  #include <linux/module.h>  #include <linux/kernel.h>  #include <linux/delay.h> -#include <linux/init.h>  #include <linux/errno.h>  #include <linux/i2c.h>  #include <linux/fs.h> @@ -187,7 +186,7 @@ static DEFINE_MUTEX(pch_mutex);  #define PCI_DEVICE_ID_ML7223_I2C	0x8010  #define PCI_DEVICE_ID_ML7831_I2C	0x8817 -static DEFINE_PCI_DEVICE_TABLE(pch_pcidev_id) = { +static const struct pci_device_id pch_pcidev_id[] = {  	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH_I2C),   1, },  	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_I2C), 2, },  	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_I2C), 1, }, @@ -312,24 +311,6 @@ static void pch_i2c_start(struct i2c_algo_pch_data *adap)  }  /** - * pch_i2c_getack() - to confirm ACK/NACK - * @adap:	Pointer to struct i2c_algo_pch_data. - */ -static s32 pch_i2c_getack(struct i2c_algo_pch_data *adap) -{ -	u32 reg_val; -	void __iomem *p = adap->pch_base_address; -	reg_val = ioread32(p + PCH_I2CSR) & PCH_GETACK; - -	if (reg_val != 0) { -		pch_err(adap, "return%d\n", -EPROTO); -		return -EPROTO; -	} - -	return 0; -} - -/**   * pch_i2c_stop() - generate stop condition in normal mode.   * @adap:	Pointer to struct i2c_algo_pch_data.   */ @@ -344,6 +325,7 @@ static void pch_i2c_stop(struct i2c_algo_pch_data *adap)  static int pch_i2c_wait_for_check_xfer(struct i2c_algo_pch_data *adap)  {  	long ret; +	void __iomem *p = adap->pch_base_address;  	ret = wait_event_timeout(pch_event,  			(adap->pch_event_flag != 0), msecs_to_jiffies(1000)); @@ -366,10 +348,9 @@ static int pch_i2c_wait_for_check_xfer(struct i2c_algo_pch_data *adap)  	adap->pch_event_flag = 0; -	if (pch_i2c_getack(adap)) { -		pch_dbg(adap, "Receive NACK for slave address" -			"setting\n"); -		return -EIO; +	if (ioread32(p + PCH_I2CSR) & PCH_GETACK) { +		pch_dbg(adap, "Receive NACK for slave address setting\n"); +		return -ENXIO;  	}  	return 0; @@ -770,10 +751,8 @@ static int pch_i2c_probe(struct pci_dev *pdev,  	pch_pci_dbg(pdev, "Entered.\n");  	adap_info = kzalloc((sizeof(struct adapter_info)), GFP_KERNEL); -	if (adap_info == NULL) { -		pch_pci_err(pdev, "Memory allocation FAILED\n"); +	if (adap_info == NULL)  		return -ENOMEM; -	}  	ret = pci_enable_device(pdev);  	if (ret) { diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c new file mode 100644 index 00000000000..63d22920285 --- /dev/null +++ b/drivers/i2c/busses/i2c-exynos5.c @@ -0,0 +1,811 @@ +/** + * i2c-exynos5.c - Samsung Exynos5 I2C Controller Driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/module.h> + +#include <linux/i2c.h> +#include <linux/time.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/spinlock.h> + +/* + * HSI2C controller from Samsung supports 2 modes of operation + * 1. Auto mode: Where in master automatically controls the whole transaction + * 2. Manual mode: Software controls the transaction by issuing commands + *    START, READ, WRITE, STOP, RESTART in I2C_MANUAL_CMD register. + * + * Operation mode can be selected by setting AUTO_MODE bit in I2C_CONF register + * + * Special bits are available for both modes of operation to set commands + * and for checking transfer status + */ + +/* Register Map */ +#define HSI2C_CTL		0x00 +#define HSI2C_FIFO_CTL		0x04 +#define HSI2C_TRAILIG_CTL	0x08 +#define HSI2C_CLK_CTL		0x0C +#define HSI2C_CLK_SLOT		0x10 +#define HSI2C_INT_ENABLE	0x20 +#define HSI2C_INT_STATUS	0x24 +#define HSI2C_ERR_STATUS	0x2C +#define HSI2C_FIFO_STATUS	0x30 +#define HSI2C_TX_DATA		0x34 +#define HSI2C_RX_DATA		0x38 +#define HSI2C_CONF		0x40 +#define HSI2C_AUTO_CONF		0x44 +#define HSI2C_TIMEOUT		0x48 +#define HSI2C_MANUAL_CMD	0x4C +#define HSI2C_TRANS_STATUS	0x50 +#define HSI2C_TIMING_HS1	0x54 +#define HSI2C_TIMING_HS2	0x58 +#define HSI2C_TIMING_HS3	0x5C +#define HSI2C_TIMING_FS1	0x60 +#define HSI2C_TIMING_FS2	0x64 +#define HSI2C_TIMING_FS3	0x68 +#define HSI2C_TIMING_SLA	0x6C +#define HSI2C_ADDR		0x70 + +/* I2C_CTL Register bits */ +#define HSI2C_FUNC_MODE_I2C			(1u << 0) +#define HSI2C_MASTER				(1u << 3) +#define HSI2C_RXCHON				(1u << 6) +#define HSI2C_TXCHON				(1u << 7) +#define HSI2C_SW_RST				(1u << 31) + +/* I2C_FIFO_CTL Register bits */ +#define HSI2C_RXFIFO_EN				(1u << 0) +#define HSI2C_TXFIFO_EN				(1u << 1) +#define HSI2C_RXFIFO_TRIGGER_LEVEL(x)		((x) << 4) +#define HSI2C_TXFIFO_TRIGGER_LEVEL(x)		((x) << 16) + +/* I2C_TRAILING_CTL Register bits */ +#define HSI2C_TRAILING_COUNT			(0xf) + +/* I2C_INT_EN Register bits */ +#define HSI2C_INT_TX_ALMOSTEMPTY_EN		(1u << 0) +#define HSI2C_INT_RX_ALMOSTFULL_EN		(1u << 1) +#define HSI2C_INT_TRAILING_EN			(1u << 6) +#define HSI2C_INT_I2C_EN			(1u << 9) + +/* I2C_INT_STAT Register bits */ +#define HSI2C_INT_TX_ALMOSTEMPTY		(1u << 0) +#define HSI2C_INT_RX_ALMOSTFULL			(1u << 1) +#define HSI2C_INT_TX_UNDERRUN			(1u << 2) +#define HSI2C_INT_TX_OVERRUN			(1u << 3) +#define HSI2C_INT_RX_UNDERRUN			(1u << 4) +#define HSI2C_INT_RX_OVERRUN			(1u << 5) +#define HSI2C_INT_TRAILING			(1u << 6) +#define HSI2C_INT_I2C				(1u << 9) + +/* I2C_FIFO_STAT Register bits */ +#define HSI2C_RX_FIFO_EMPTY			(1u << 24) +#define HSI2C_RX_FIFO_FULL			(1u << 23) +#define HSI2C_RX_FIFO_LVL(x)			((x >> 16) & 0x7f) +#define HSI2C_TX_FIFO_EMPTY			(1u << 8) +#define HSI2C_TX_FIFO_FULL			(1u << 7) +#define HSI2C_TX_FIFO_LVL(x)			((x >> 0) & 0x7f) + +/* I2C_CONF Register bits */ +#define HSI2C_AUTO_MODE				(1u << 31) +#define HSI2C_10BIT_ADDR_MODE			(1u << 30) +#define HSI2C_HS_MODE				(1u << 29) + +/* I2C_AUTO_CONF Register bits */ +#define HSI2C_READ_WRITE			(1u << 16) +#define HSI2C_STOP_AFTER_TRANS			(1u << 17) +#define HSI2C_MASTER_RUN			(1u << 31) + +/* I2C_TIMEOUT Register bits */ +#define HSI2C_TIMEOUT_EN			(1u << 31) +#define HSI2C_TIMEOUT_MASK			0xff + +/* I2C_TRANS_STATUS register bits */ +#define HSI2C_MASTER_BUSY			(1u << 17) +#define HSI2C_SLAVE_BUSY			(1u << 16) +#define HSI2C_TIMEOUT_AUTO			(1u << 4) +#define HSI2C_NO_DEV				(1u << 3) +#define HSI2C_NO_DEV_ACK			(1u << 2) +#define HSI2C_TRANS_ABORT			(1u << 1) +#define HSI2C_TRANS_DONE			(1u << 0) + +/* I2C_ADDR register bits */ +#define HSI2C_SLV_ADDR_SLV(x)			((x & 0x3ff) << 0) +#define HSI2C_SLV_ADDR_MAS(x)			((x & 0x3ff) << 10) +#define HSI2C_MASTER_ID(x)			((x & 0xff) << 24) +#define MASTER_ID(x)				((x & 0x7) + 0x08) + +/* + * Controller operating frequency, timing values for operation + * are calculated against this frequency + */ +#define HSI2C_HS_TX_CLOCK	1000000 +#define HSI2C_FS_TX_CLOCK	100000 +#define HSI2C_HIGH_SPD		1 +#define HSI2C_FAST_SPD		0 + +#define EXYNOS5_I2C_TIMEOUT (msecs_to_jiffies(1000)) + +struct exynos5_i2c { +	struct i2c_adapter	adap; +	unsigned int		suspended:1; + +	struct i2c_msg		*msg; +	struct completion	msg_complete; +	unsigned int		msg_ptr; + +	unsigned int		irq; + +	void __iomem		*regs; +	struct clk		*clk; +	struct device		*dev; +	int			state; + +	spinlock_t		lock;		/* IRQ synchronization */ + +	/* +	 * Since the TRANS_DONE bit is cleared on read, and we may read it +	 * either during an IRQ or after a transaction, keep track of its +	 * state here. +	 */ +	int			trans_done; + +	/* Controller operating frequency */ +	unsigned int		fs_clock; +	unsigned int		hs_clock; + +	/* +	 * HSI2C Controller can operate in +	 * 1. High speed upto 3.4Mbps +	 * 2. Fast speed upto 1Mbps +	 */ +	int			speed_mode; + +	/* Version of HS-I2C Hardware */ +	struct exynos_hsi2c_variant	*variant; +}; + +/** + * struct exynos_hsi2c_variant - platform specific HSI2C driver data + * @fifo_depth: the fifo depth supported by the HSI2C module + * + * Specifies platform specific configuration of HSI2C module. + * Note: A structure for driver specific platform data is used for future + * expansion of its usage. + */ +struct exynos_hsi2c_variant { +	unsigned int	fifo_depth; +}; + +static const struct exynos_hsi2c_variant exynos5250_hsi2c_data = { +	.fifo_depth	= 64, +}; + +static const struct exynos_hsi2c_variant exynos5260_hsi2c_data = { +	.fifo_depth	= 16, +}; + +static const struct of_device_id exynos5_i2c_match[] = { +	{ +		.compatible = "samsung,exynos5-hsi2c", +		.data = &exynos5250_hsi2c_data +	}, { +		.compatible = "samsung,exynos5250-hsi2c", +		.data = &exynos5250_hsi2c_data +	}, { +		.compatible = "samsung,exynos5260-hsi2c", +		.data = &exynos5260_hsi2c_data +	}, {}, +}; +MODULE_DEVICE_TABLE(of, exynos5_i2c_match); + +static inline struct exynos_hsi2c_variant *exynos5_i2c_get_variant +					(struct platform_device *pdev) +{ +	const struct of_device_id *match; + +	match = of_match_node(exynos5_i2c_match, pdev->dev.of_node); +	return (struct exynos_hsi2c_variant *)match->data; +} + +static void exynos5_i2c_clr_pend_irq(struct exynos5_i2c *i2c) +{ +	writel(readl(i2c->regs + HSI2C_INT_STATUS), +				i2c->regs + HSI2C_INT_STATUS); +} + +/* + * exynos5_i2c_set_timing: updates the registers with appropriate + * timing values calculated + * + * Returns 0 on success, -EINVAL if the cycle length cannot + * be calculated. + */ +static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, int mode) +{ +	u32 i2c_timing_s1; +	u32 i2c_timing_s2; +	u32 i2c_timing_s3; +	u32 i2c_timing_sla; +	unsigned int t_start_su, t_start_hd; +	unsigned int t_stop_su; +	unsigned int t_data_su, t_data_hd; +	unsigned int t_scl_l, t_scl_h; +	unsigned int t_sr_release; +	unsigned int t_ftl_cycle; +	unsigned int clkin = clk_get_rate(i2c->clk); +	unsigned int div, utemp0 = 0, utemp1 = 0, clk_cycle; +	unsigned int op_clk = (mode == HSI2C_HIGH_SPD) ? +				i2c->hs_clock : i2c->fs_clock; + +	/* +	 * FPCLK / FI2C = +	 * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE +	 * utemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) +	 * utemp1 = (TSCLK_L + TSCLK_H + 2) +	 */ +	t_ftl_cycle = (readl(i2c->regs + HSI2C_CONF) >> 16) & 0x7; +	utemp0 = (clkin / op_clk) - 8 - 2 * t_ftl_cycle; + +	/* CLK_DIV max is 256 */ +	for (div = 0; div < 256; div++) { +		utemp1 = utemp0 / (div + 1); + +		/* +		 * SCL_L and SCL_H each has max value of 255 +		 * Hence, For the clk_cycle to the have right value +		 * utemp1 has to be less then 512 and more than 4. +		 */ +		if ((utemp1 < 512) && (utemp1 > 4)) { +			clk_cycle = utemp1 - 2; +			break; +		} else if (div == 255) { +			dev_warn(i2c->dev, "Failed to calculate divisor"); +			return -EINVAL; +		} +	} + +	t_scl_l = clk_cycle / 2; +	t_scl_h = clk_cycle / 2; +	t_start_su = t_scl_l; +	t_start_hd = t_scl_l; +	t_stop_su = t_scl_l; +	t_data_su = t_scl_l / 2; +	t_data_hd = t_scl_l / 2; +	t_sr_release = clk_cycle; + +	i2c_timing_s1 = t_start_su << 24 | t_start_hd << 16 | t_stop_su << 8; +	i2c_timing_s2 = t_data_su << 24 | t_scl_l << 8 | t_scl_h << 0; +	i2c_timing_s3 = div << 16 | t_sr_release << 0; +	i2c_timing_sla = t_data_hd << 0; + +	dev_dbg(i2c->dev, "tSTART_SU: %X, tSTART_HD: %X, tSTOP_SU: %X\n", +		t_start_su, t_start_hd, t_stop_su); +	dev_dbg(i2c->dev, "tDATA_SU: %X, tSCL_L: %X, tSCL_H: %X\n", +		t_data_su, t_scl_l, t_scl_h); +	dev_dbg(i2c->dev, "nClkDiv: %X, tSR_RELEASE: %X\n", +		div, t_sr_release); +	dev_dbg(i2c->dev, "tDATA_HD: %X\n", t_data_hd); + +	if (mode == HSI2C_HIGH_SPD) { +		writel(i2c_timing_s1, i2c->regs + HSI2C_TIMING_HS1); +		writel(i2c_timing_s2, i2c->regs + HSI2C_TIMING_HS2); +		writel(i2c_timing_s3, i2c->regs + HSI2C_TIMING_HS3); +	} else { +		writel(i2c_timing_s1, i2c->regs + HSI2C_TIMING_FS1); +		writel(i2c_timing_s2, i2c->regs + HSI2C_TIMING_FS2); +		writel(i2c_timing_s3, i2c->regs + HSI2C_TIMING_FS3); +	} +	writel(i2c_timing_sla, i2c->regs + HSI2C_TIMING_SLA); + +	return 0; +} + +static int exynos5_hsi2c_clock_setup(struct exynos5_i2c *i2c) +{ +	/* +	 * Configure the Fast speed timing values +	 * Even the High Speed mode initially starts with Fast mode +	 */ +	if (exynos5_i2c_set_timing(i2c, HSI2C_FAST_SPD)) { +		dev_err(i2c->dev, "HSI2C FS Clock set up failed\n"); +		return -EINVAL; +	} + +	/* configure the High speed timing values */ +	if (i2c->speed_mode == HSI2C_HIGH_SPD) { +		if (exynos5_i2c_set_timing(i2c, HSI2C_HIGH_SPD)) { +			dev_err(i2c->dev, "HSI2C HS Clock set up failed\n"); +			return -EINVAL; +		} +	} + +	return 0; +} + +/* + * exynos5_i2c_init: configures the controller for I2C functionality + * Programs I2C controller for Master mode operation + */ +static void exynos5_i2c_init(struct exynos5_i2c *i2c) +{ +	u32 i2c_conf = readl(i2c->regs + HSI2C_CONF); +	u32 i2c_timeout = readl(i2c->regs + HSI2C_TIMEOUT); + +	/* Clear to disable Timeout */ +	i2c_timeout &= ~HSI2C_TIMEOUT_EN; +	writel(i2c_timeout, i2c->regs + HSI2C_TIMEOUT); + +	writel((HSI2C_FUNC_MODE_I2C | HSI2C_MASTER), +					i2c->regs + HSI2C_CTL); +	writel(HSI2C_TRAILING_COUNT, i2c->regs + HSI2C_TRAILIG_CTL); + +	if (i2c->speed_mode == HSI2C_HIGH_SPD) { +		writel(HSI2C_MASTER_ID(MASTER_ID(i2c->adap.nr)), +					i2c->regs + HSI2C_ADDR); +		i2c_conf |= HSI2C_HS_MODE; +	} + +	writel(i2c_conf | HSI2C_AUTO_MODE, i2c->regs + HSI2C_CONF); +} + +static void exynos5_i2c_reset(struct exynos5_i2c *i2c) +{ +	u32 i2c_ctl; + +	/* Set and clear the bit for reset */ +	i2c_ctl = readl(i2c->regs + HSI2C_CTL); +	i2c_ctl |= HSI2C_SW_RST; +	writel(i2c_ctl, i2c->regs + HSI2C_CTL); + +	i2c_ctl = readl(i2c->regs + HSI2C_CTL); +	i2c_ctl &= ~HSI2C_SW_RST; +	writel(i2c_ctl, i2c->regs + HSI2C_CTL); + +	/* We don't expect calculations to fail during the run */ +	exynos5_hsi2c_clock_setup(i2c); +	/* Initialize the configure registers */ +	exynos5_i2c_init(i2c); +} + +/* + * exynos5_i2c_irq: top level IRQ servicing routine + * + * INT_STATUS registers gives the interrupt details. Further, + * FIFO_STATUS or TRANS_STATUS registers are to be check for detailed + * state of the bus. + */ +static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id) +{ +	struct exynos5_i2c *i2c = dev_id; +	u32 fifo_level, int_status, fifo_status, trans_status; +	unsigned char byte; +	int len = 0; + +	i2c->state = -EINVAL; + +	spin_lock(&i2c->lock); + +	int_status = readl(i2c->regs + HSI2C_INT_STATUS); +	writel(int_status, i2c->regs + HSI2C_INT_STATUS); +	fifo_status = readl(i2c->regs + HSI2C_FIFO_STATUS); + +	/* handle interrupt related to the transfer status */ +	if (int_status & HSI2C_INT_I2C) { +		trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS); +		if (trans_status & HSI2C_NO_DEV_ACK) { +			dev_dbg(i2c->dev, "No ACK from device\n"); +			i2c->state = -ENXIO; +			goto stop; +		} else if (trans_status & HSI2C_NO_DEV) { +			dev_dbg(i2c->dev, "No device\n"); +			i2c->state = -ENXIO; +			goto stop; +		} else if (trans_status & HSI2C_TRANS_ABORT) { +			dev_dbg(i2c->dev, "Deal with arbitration lose\n"); +			i2c->state = -EAGAIN; +			goto stop; +		} else if (trans_status & HSI2C_TIMEOUT_AUTO) { +			dev_dbg(i2c->dev, "Accessing device timed out\n"); +			i2c->state = -EAGAIN; +			goto stop; +		} else if (trans_status & HSI2C_TRANS_DONE) { +			i2c->trans_done = 1; +			i2c->state = 0; +		} +	} + +	if ((i2c->msg->flags & I2C_M_RD) && (int_status & +			(HSI2C_INT_TRAILING | HSI2C_INT_RX_ALMOSTFULL))) { +		fifo_status = readl(i2c->regs + HSI2C_FIFO_STATUS); +		fifo_level = HSI2C_RX_FIFO_LVL(fifo_status); +		len = min(fifo_level, i2c->msg->len - i2c->msg_ptr); + +		while (len > 0) { +			byte = (unsigned char) +				readl(i2c->regs + HSI2C_RX_DATA); +			i2c->msg->buf[i2c->msg_ptr++] = byte; +			len--; +		} +		i2c->state = 0; +	} else if (int_status & HSI2C_INT_TX_ALMOSTEMPTY) { +		fifo_status = readl(i2c->regs + HSI2C_FIFO_STATUS); +		fifo_level = HSI2C_TX_FIFO_LVL(fifo_status); + +		len = i2c->variant->fifo_depth - fifo_level; +		if (len > (i2c->msg->len - i2c->msg_ptr)) +			len = i2c->msg->len - i2c->msg_ptr; + +		while (len > 0) { +			byte = i2c->msg->buf[i2c->msg_ptr++]; +			writel(byte, i2c->regs + HSI2C_TX_DATA); +			len--; +		} +		i2c->state = 0; +	} + + stop: +	if ((i2c->trans_done && (i2c->msg->len == i2c->msg_ptr)) || +	    (i2c->state < 0)) { +		writel(0, i2c->regs + HSI2C_INT_ENABLE); +		exynos5_i2c_clr_pend_irq(i2c); +		complete(&i2c->msg_complete); +	} + +	spin_unlock(&i2c->lock); + +	return IRQ_HANDLED; +} + +/* + * exynos5_i2c_wait_bus_idle + * + * Wait for the bus to go idle, indicated by the MASTER_BUSY bit being + * cleared. + * + * Returns -EBUSY if the bus cannot be bought to idle + */ +static int exynos5_i2c_wait_bus_idle(struct exynos5_i2c *i2c) +{ +	unsigned long stop_time; +	u32 trans_status; + +	/* wait for 100 milli seconds for the bus to be idle */ +	stop_time = jiffies + msecs_to_jiffies(100) + 1; +	do { +		trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS); +		if (!(trans_status & HSI2C_MASTER_BUSY)) +			return 0; + +		usleep_range(50, 200); +	} while (time_before(jiffies, stop_time)); + +	return -EBUSY; +} + +/* + * exynos5_i2c_message_start: Configures the bus and starts the xfer + * i2c: struct exynos5_i2c pointer for the current bus + * stop: Enables stop after transfer if set. Set for last transfer of + *       in the list of messages. + * + * Configures the bus for read/write function + * Sets chip address to talk to, message length to be sent. + * Enables appropriate interrupts and sends start xfer command. + */ +static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop) +{ +	u32 i2c_ctl; +	u32 int_en = HSI2C_INT_I2C_EN; +	u32 i2c_auto_conf = 0; +	u32 fifo_ctl; +	unsigned long flags; +	unsigned short trig_lvl; + +	i2c_ctl = readl(i2c->regs + HSI2C_CTL); +	i2c_ctl &= ~(HSI2C_TXCHON | HSI2C_RXCHON); +	fifo_ctl = HSI2C_RXFIFO_EN | HSI2C_TXFIFO_EN; + +	if (i2c->msg->flags & I2C_M_RD) { +		i2c_ctl |= HSI2C_RXCHON; + +		i2c_auto_conf = HSI2C_READ_WRITE; + +		trig_lvl = (i2c->msg->len > i2c->variant->fifo_depth) ? +			(i2c->variant->fifo_depth * 3 / 4) : i2c->msg->len; +		fifo_ctl |= HSI2C_RXFIFO_TRIGGER_LEVEL(trig_lvl); + +		int_en |= (HSI2C_INT_RX_ALMOSTFULL_EN | +			HSI2C_INT_TRAILING_EN); +	} else { +		i2c_ctl |= HSI2C_TXCHON; + +		trig_lvl = (i2c->msg->len > i2c->variant->fifo_depth) ? +			(i2c->variant->fifo_depth * 1 / 4) : i2c->msg->len; +		fifo_ctl |= HSI2C_TXFIFO_TRIGGER_LEVEL(trig_lvl); + +		int_en |= HSI2C_INT_TX_ALMOSTEMPTY_EN; +	} + +	writel(HSI2C_SLV_ADDR_MAS(i2c->msg->addr), i2c->regs + HSI2C_ADDR); + +	writel(fifo_ctl, i2c->regs + HSI2C_FIFO_CTL); +	writel(i2c_ctl, i2c->regs + HSI2C_CTL); + + +	/* +	 * Enable interrupts before starting the transfer so that we don't +	 * miss any INT_I2C interrupts. +	 */ +	spin_lock_irqsave(&i2c->lock, flags); +	writel(int_en, i2c->regs + HSI2C_INT_ENABLE); + +	if (stop == 1) +		i2c_auto_conf |= HSI2C_STOP_AFTER_TRANS; +	i2c_auto_conf |= i2c->msg->len; +	i2c_auto_conf |= HSI2C_MASTER_RUN; +	writel(i2c_auto_conf, i2c->regs + HSI2C_AUTO_CONF); +	spin_unlock_irqrestore(&i2c->lock, flags); +} + +static int exynos5_i2c_xfer_msg(struct exynos5_i2c *i2c, +			      struct i2c_msg *msgs, int stop) +{ +	unsigned long timeout; +	int ret; + +	i2c->msg = msgs; +	i2c->msg_ptr = 0; +	i2c->trans_done = 0; + +	reinit_completion(&i2c->msg_complete); + +	exynos5_i2c_message_start(i2c, stop); + +	timeout = wait_for_completion_timeout(&i2c->msg_complete, +					      EXYNOS5_I2C_TIMEOUT); +	if (timeout == 0) +		ret = -ETIMEDOUT; +	else +		ret = i2c->state; + +	/* +	 * If this is the last message to be transfered (stop == 1) +	 * Then check if the bus can be brought back to idle. +	 */ +	if (ret == 0 && stop) +		ret = exynos5_i2c_wait_bus_idle(i2c); + +	if (ret < 0) { +		exynos5_i2c_reset(i2c); +		if (ret == -ETIMEDOUT) +			dev_warn(i2c->dev, "%s timeout\n", +				 (msgs->flags & I2C_M_RD) ? "rx" : "tx"); +	} + +	/* Return the state as in interrupt routine */ +	return ret; +} + +static int exynos5_i2c_xfer(struct i2c_adapter *adap, +			struct i2c_msg *msgs, int num) +{ +	struct exynos5_i2c *i2c = adap->algo_data; +	int i = 0, ret = 0, stop = 0; + +	if (i2c->suspended) { +		dev_err(i2c->dev, "HS-I2C is not initialized.\n"); +		return -EIO; +	} + +	clk_prepare_enable(i2c->clk); + +	for (i = 0; i < num; i++, msgs++) { +		stop = (i == num - 1); + +		ret = exynos5_i2c_xfer_msg(i2c, msgs, stop); + +		if (ret < 0) +			goto out; +	} + +	if (i == num) { +		ret = num; +	} else { +		/* Only one message, cannot access the device */ +		if (i == 1) +			ret = -EREMOTEIO; +		else +			ret = i; + +		dev_warn(i2c->dev, "xfer message failed\n"); +	} + + out: +	clk_disable_unprepare(i2c->clk); +	return ret; +} + +static u32 exynos5_i2c_func(struct i2c_adapter *adap) +{ +	return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); +} + +static const struct i2c_algorithm exynos5_i2c_algorithm = { +	.master_xfer		= exynos5_i2c_xfer, +	.functionality		= exynos5_i2c_func, +}; + +static int exynos5_i2c_probe(struct platform_device *pdev) +{ +	struct device_node *np = pdev->dev.of_node; +	struct exynos5_i2c *i2c; +	struct resource *mem; +	unsigned int op_clock; +	int ret; + +	i2c = devm_kzalloc(&pdev->dev, sizeof(struct exynos5_i2c), GFP_KERNEL); +	if (!i2c) +		return -ENOMEM; + +	if (of_property_read_u32(np, "clock-frequency", &op_clock)) { +		i2c->speed_mode = HSI2C_FAST_SPD; +		i2c->fs_clock = HSI2C_FS_TX_CLOCK; +	} else { +		if (op_clock >= HSI2C_HS_TX_CLOCK) { +			i2c->speed_mode = HSI2C_HIGH_SPD; +			i2c->fs_clock = HSI2C_FS_TX_CLOCK; +			i2c->hs_clock = op_clock; +		} else { +			i2c->speed_mode = HSI2C_FAST_SPD; +			i2c->fs_clock = op_clock; +		} +	} + +	strlcpy(i2c->adap.name, "exynos5-i2c", sizeof(i2c->adap.name)); +	i2c->adap.owner   = THIS_MODULE; +	i2c->adap.algo    = &exynos5_i2c_algorithm; +	i2c->adap.retries = 3; + +	i2c->dev = &pdev->dev; +	i2c->clk = devm_clk_get(&pdev->dev, "hsi2c"); +	if (IS_ERR(i2c->clk)) { +		dev_err(&pdev->dev, "cannot get clock\n"); +		return -ENOENT; +	} + +	clk_prepare_enable(i2c->clk); + +	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	i2c->regs = devm_ioremap_resource(&pdev->dev, mem); +	if (IS_ERR(i2c->regs)) { +		ret = PTR_ERR(i2c->regs); +		goto err_clk; +	} + +	i2c->adap.dev.of_node = np; +	i2c->adap.algo_data = i2c; +	i2c->adap.dev.parent = &pdev->dev; + +	/* Clear pending interrupts from u-boot or misc causes */ +	exynos5_i2c_clr_pend_irq(i2c); + +	spin_lock_init(&i2c->lock); +	init_completion(&i2c->msg_complete); + +	i2c->irq = ret = platform_get_irq(pdev, 0); +	if (ret <= 0) { +		dev_err(&pdev->dev, "cannot find HS-I2C IRQ\n"); +		ret = -EINVAL; +		goto err_clk; +	} + +	ret = devm_request_irq(&pdev->dev, i2c->irq, exynos5_i2c_irq, +				IRQF_NO_SUSPEND | IRQF_ONESHOT, +				dev_name(&pdev->dev), i2c); + +	if (ret != 0) { +		dev_err(&pdev->dev, "cannot request HS-I2C IRQ %d\n", i2c->irq); +		goto err_clk; +	} + +	ret = exynos5_hsi2c_clock_setup(i2c); +	if (ret) +		goto err_clk; + +	i2c->variant = exynos5_i2c_get_variant(pdev); + +	exynos5_i2c_reset(i2c); + +	ret = i2c_add_adapter(&i2c->adap); +	if (ret < 0) { +		dev_err(&pdev->dev, "failed to add bus to i2c core\n"); +		goto err_clk; +	} + +	platform_set_drvdata(pdev, i2c); + + err_clk: +	clk_disable_unprepare(i2c->clk); +	return ret; +} + +static int exynos5_i2c_remove(struct platform_device *pdev) +{ +	struct exynos5_i2c *i2c = platform_get_drvdata(pdev); + +	i2c_del_adapter(&i2c->adap); + +	return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int exynos5_i2c_suspend_noirq(struct device *dev) +{ +	struct platform_device *pdev = to_platform_device(dev); +	struct exynos5_i2c *i2c = platform_get_drvdata(pdev); + +	i2c->suspended = 1; + +	return 0; +} + +static int exynos5_i2c_resume_noirq(struct device *dev) +{ +	struct platform_device *pdev = to_platform_device(dev); +	struct exynos5_i2c *i2c = platform_get_drvdata(pdev); +	int ret = 0; + +	clk_prepare_enable(i2c->clk); + +	ret = exynos5_hsi2c_clock_setup(i2c); +	if (ret) { +		clk_disable_unprepare(i2c->clk); +		return ret; +	} + +	exynos5_i2c_init(i2c); +	clk_disable_unprepare(i2c->clk); +	i2c->suspended = 0; + +	return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(exynos5_i2c_dev_pm_ops, exynos5_i2c_suspend_noirq, +			 exynos5_i2c_resume_noirq); + +static struct platform_driver exynos5_i2c_driver = { +	.probe		= exynos5_i2c_probe, +	.remove		= exynos5_i2c_remove, +	.driver		= { +		.owner	= THIS_MODULE, +		.name	= "exynos5-hsi2c", +		.pm	= &exynos5_i2c_dev_pm_ops, +		.of_match_table = exynos5_i2c_match, +	}, +}; + +module_platform_driver(exynos5_i2c_driver); + +MODULE_DESCRIPTION("Exynos5 HS-I2C Bus driver"); +MODULE_AUTHOR("Naveen Krishna Chatradhi, <ch.naveen@samsung.com>"); +MODULE_AUTHOR("Taekgyun Ko, <taeggyun.ko@samsung.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c index bfa02c6c2dd..71a45b210a2 100644 --- a/drivers/i2c/busses/i2c-gpio.c +++ b/drivers/i2c/busses/i2c-gpio.c @@ -15,6 +15,7 @@  #include <linux/slab.h>  #include <linux/platform_device.h>  #include <linux/gpio.h> +#include <linux/of.h>  #include <linux/of_gpio.h>  struct i2c_gpio_private_data { @@ -93,6 +94,9 @@ static int of_i2c_gpio_get_pins(struct device_node *np,  	*sda_pin = of_get_gpio(np, 0);  	*scl_pin = of_get_gpio(np, 1); +	if (*sda_pin == -EPROBE_DEFER || *scl_pin == -EPROBE_DEFER) +		return -EPROBE_DEFER; +  	if (!gpio_is_valid(*sda_pin) || !gpio_is_valid(*scl_pin)) {  		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",  		       np->full_name, *sda_pin, *scl_pin); @@ -143,24 +147,22 @@ static int i2c_gpio_probe(struct platform_device *pdev)  		scl_pin = pdata->scl_pin;  	} -	ret = gpio_request(sda_pin, "sda"); +	ret = devm_gpio_request(&pdev->dev, sda_pin, "sda");  	if (ret) {  		if (ret == -EINVAL)  			ret = -EPROBE_DEFER;	/* Try again later */ -		goto err_request_sda; +		return ret;  	} -	ret = gpio_request(scl_pin, "scl"); +	ret = devm_gpio_request(&pdev->dev, scl_pin, "scl");  	if (ret) {  		if (ret == -EINVAL)  			ret = -EPROBE_DEFER;	/* Try again later */ -		goto err_request_scl; +		return ret;  	}  	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); -	if (!priv) { -		ret = -ENOMEM; -		goto err_add_bus; -	} +	if (!priv) +		return -ENOMEM;  	adap = &priv->adap;  	bit_data = &priv->bit_data;  	pdata = &priv->pdata; @@ -221,7 +223,7 @@ static int i2c_gpio_probe(struct platform_device *pdev)  	adap->nr = pdev->id;  	ret = i2c_bit_add_numbered_bus(adap);  	if (ret) -		goto err_add_bus; +		return ret;  	platform_set_drvdata(pdev, priv); @@ -231,13 +233,6 @@ static int i2c_gpio_probe(struct platform_device *pdev)  		 ? ", no clock stretching" : "");  	return 0; - -err_add_bus: -	gpio_free(scl_pin); -err_request_scl: -	gpio_free(sda_pin); -err_request_sda: -	return ret;  }  static int i2c_gpio_remove(struct platform_device *pdev) @@ -251,8 +246,6 @@ static int i2c_gpio_remove(struct platform_device *pdev)  	pdata = &priv->pdata;  	i2c_del_adapter(adap); -	gpio_free(pdata->scl_pin); -	gpio_free(pdata->sda_pin);  	return 0;  } diff --git a/drivers/i2c/busses/i2c-highlander.c b/drivers/i2c/busses/i2c-highlander.c index 436b0f25491..512fcfabc18 100644 --- a/drivers/i2c/busses/i2c-highlander.c +++ b/drivers/i2c/busses/i2c-highlander.c @@ -12,7 +12,6 @@   * of this archive for more details.   */  #include <linux/module.h> -#include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/i2c.h>  #include <linux/platform_device.h> diff --git a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c index 79c3d9069a4..14d2b76de25 100644 --- a/drivers/i2c/busses/i2c-hydra.c +++ b/drivers/i2c/busses/i2c-hydra.c @@ -27,7 +27,6 @@  #include <linux/types.h>  #include <linux/i2c.h>  #include <linux/i2c-algo-bit.h> -#include <linux/init.h>  #include <linux/io.h>  #include <asm/hydra.h> @@ -105,7 +104,7 @@ static struct i2c_adapter hydra_adap = {  	.algo_data	= &hydra_bit_data,  }; -static DEFINE_PCI_DEVICE_TABLE(hydra_ids) = { +static const struct pci_device_id hydra_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_HYDRA) },  	{ 0, }  }; diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 4296d172127..6777cd6f877 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -2,7 +2,7 @@      Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,      Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker      <mdsxyz123@yahoo.com> -    Copyright (C) 2007 - 2012  Jean Delvare <khali@linux-fr.org> +    Copyright (C) 2007 - 2012  Jean Delvare <jdelvare@suse.de>      Copyright (C) 2010         Intel Corporation,                                 David Woodhouse <dwmw2@infradead.org> @@ -59,6 +59,8 @@    Wellsburg (PCH) MS    0x8d7e     32     hard     yes     yes     yes    Wellsburg (PCH) MS    0x8d7f     32     hard     yes     yes     yes    Coleto Creek (PCH)    0x23b0     32     hard     yes     yes     yes +  Wildcat Point-LP (PCH)   0x9ca2     32     hard     yes     yes     yes +  BayTrail (SOC)        0x0f12     32     hard     yes     yes     yes    Features supported by this driver:    Software PEC                     no @@ -160,6 +162,7 @@  				 STATUS_ERROR_FLAGS)  /* Older devices have their ID defined in <linux/pci_ids.h> */ +#define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS	0x0f12  #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS	0x1c22  #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS	0x1d22  /* Patsburg also has three 'Integrated Device Function' SMBus controllers */ @@ -177,6 +180,7 @@  #define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1	0x8d7e  #define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2	0x8d7f  #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS	0x9c22 +#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS	0x9ca2  struct i801_mux_config {  	char *gpio_chip; @@ -787,7 +791,7 @@ static const struct i2c_algorithm smbus_algorithm = {  	.functionality	= i801_func,  }; -static DEFINE_PCI_DEVICE_TABLE(i801_ids) = { +static const struct pci_device_id i801_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) }, @@ -819,6 +823,8 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = {  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS) }, +	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_SMBUS) }, +	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS) },  	{ 0, }  }; @@ -1309,8 +1315,7 @@ static void __exit i2c_i801_exit(void)  	pci_unregister_driver(&i801_driver);  } -MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>, " -	      "Jean Delvare <khali@linux-fr.org>"); +MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>, Jean Delvare <jdelvare@suse.de>");  MODULE_DESCRIPTION("I801 SMBus driver");  MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index ff3caa0c28c..274312c96b1 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -36,11 +36,12 @@  #include <linux/ioport.h>  #include <linux/delay.h>  #include <linux/slab.h> -#include <linux/init.h>  #include <linux/interrupt.h>  #include <asm/irq.h>  #include <linux/io.h>  #include <linux/i2c.h> +#include <linux/of_address.h> +#include <linux/of_irq.h>  #include <linux/of_platform.h>  #include "i2c-ibm_iic.h" diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index ccf46656bda..aa8bc146718 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -183,6 +183,8 @@ struct imx_i2c_struct {  	unsigned int 		disable_delay;  	int			stopped;  	unsigned int		ifdr; /* IMX_I2C_IFDR */ +	unsigned int		cur_clk; +	unsigned int		bitrate;  	const struct imx_i2c_hwdata	*hwdata;  }; @@ -305,6 +307,48 @@ static int i2c_imx_acked(struct imx_i2c_struct *i2c_imx)  	return 0;  } +static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx) +{ +	struct imx_i2c_clk_pair *i2c_clk_div = i2c_imx->hwdata->clk_div; +	unsigned int i2c_clk_rate; +	unsigned int div; +	int i; + +	/* Divider value calculation */ +	i2c_clk_rate = clk_get_rate(i2c_imx->clk); +	if (i2c_imx->cur_clk == i2c_clk_rate) +		return; +	else +		i2c_imx->cur_clk = i2c_clk_rate; + +	div = (i2c_clk_rate + i2c_imx->bitrate - 1) / i2c_imx->bitrate; +	if (div < i2c_clk_div[0].div) +		i = 0; +	else if (div > i2c_clk_div[i2c_imx->hwdata->ndivs - 1].div) +		i = i2c_imx->hwdata->ndivs - 1; +	else +		for (i = 0; i2c_clk_div[i].div < div; i++); + +	/* Store divider value */ +	i2c_imx->ifdr = i2c_clk_div[i].val; + +	/* +	 * There dummy delay is calculated. +	 * It should be about one I2C clock period long. +	 * This delay is used in I2C bus disable function +	 * to fix chip hardware bug. +	 */ +	i2c_imx->disable_delay = (500000U * i2c_clk_div[i].div +		+ (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2); + +#ifdef CONFIG_I2C_DEBUG_BUS +	dev_dbg(&i2c_imx->adapter.dev, "I2C_CLK=%d, REQ DIV=%d\n", +		i2c_clk_rate, div); +	dev_dbg(&i2c_imx->adapter.dev, "IFDR[IC]=0x%x, REAL DIV=%d\n", +		i2c_clk_div[i].val, i2c_clk_div[i].div); +#endif +} +  static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)  {  	unsigned int temp = 0; @@ -312,7 +356,11 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)  	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); -	clk_prepare_enable(i2c_imx->clk); +	i2c_imx_set_clk(i2c_imx); + +	result = clk_prepare_enable(i2c_imx->clk); +	if (result) +		return result;  	imx_i2c_write_reg(i2c_imx->ifdr, i2c_imx, IMX_I2C_IFDR);  	/* Enable I2C controller */  	imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR); @@ -365,45 +413,6 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)  	clk_disable_unprepare(i2c_imx->clk);  } -static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx, -							unsigned int rate) -{ -	struct imx_i2c_clk_pair *i2c_clk_div = i2c_imx->hwdata->clk_div; -	unsigned int i2c_clk_rate; -	unsigned int div; -	int i; - -	/* Divider value calculation */ -	i2c_clk_rate = clk_get_rate(i2c_imx->clk); -	div = (i2c_clk_rate + rate - 1) / rate; -	if (div < i2c_clk_div[0].div) -		i = 0; -	else if (div > i2c_clk_div[i2c_imx->hwdata->ndivs - 1].div) -		i = i2c_imx->hwdata->ndivs - 1; -	else -		for (i = 0; i2c_clk_div[i].div < div; i++); - -	/* Store divider value */ -	i2c_imx->ifdr = i2c_clk_div[i].val; - -	/* -	 * There dummy delay is calculated. -	 * It should be about one I2C clock period long. -	 * This delay is used in I2C bus disable function -	 * to fix chip hardware bug. -	 */ -	i2c_imx->disable_delay = (500000U * i2c_clk_div[i].div -		+ (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2); - -	/* dev_dbg() can't be used, because adapter is not yet registered */ -#ifdef CONFIG_I2C_DEBUG_BUS -	dev_dbg(&i2c_imx->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n", -		__func__, i2c_clk_rate, div); -	dev_dbg(&i2c_imx->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n", -		__func__, i2c_clk_div[i].val, i2c_clk_div[i].div); -#endif -} -  static irqreturn_t i2c_imx_isr(int irq, void *dev_id)  {  	struct imx_i2c_struct *i2c_imx = dev_id; @@ -456,10 +465,11 @@ static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)  	return 0;  } -static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs) +static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bool is_lastmsg)  {  	int i, result;  	unsigned int temp; +	int block_data = msgs->flags & I2C_M_RECV_LEN;  	dev_dbg(&i2c_imx->adapter.dev,  		"<%s> write slave address: addr=0x%x\n", @@ -479,7 +489,12 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)  	/* setup bus to read data */  	temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);  	temp &= ~I2CR_MTX; -	if (msgs->len - 1) + +	/* +	 * Reset the I2CR_TXAK flag initially for SMBus block read since the +	 * length is unknown +	 */ +	if ((msgs->len - 1) || block_data)  		temp &= ~I2CR_TXAK;  	imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);  	imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR); /* dummy read */ @@ -488,19 +503,49 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)  	/* read data */  	for (i = 0; i < msgs->len; i++) { +		u8 len = 0;  		result = i2c_imx_trx_complete(i2c_imx);  		if (result)  			return result; -		if (i == (msgs->len - 1)) { -			/* It must generate STOP before read I2DR to prevent -			   controller from generating another clock cycle */ +		/* +		 * First byte is the length of remaining packet +		 * in the SMBus block data read. Add it to +		 * msgs->len. +		 */ +		if ((!i) && block_data) { +			len = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR); +			if ((len == 0) || (len > I2C_SMBUS_BLOCK_MAX)) +				return -EPROTO;  			dev_dbg(&i2c_imx->adapter.dev, -				"<%s> clear MSTA\n", __func__); -			temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); -			temp &= ~(I2CR_MSTA | I2CR_MTX); -			imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); -			i2c_imx_bus_busy(i2c_imx, 0); -			i2c_imx->stopped = 1; +				"<%s> read length: 0x%X\n", +				__func__, len); +			msgs->len += len; +		} +		if (i == (msgs->len - 1)) { +			if (is_lastmsg) { +				/* +				 * It must generate STOP before read I2DR to prevent +				 * controller from generating another clock cycle +				 */ +				dev_dbg(&i2c_imx->adapter.dev, +					"<%s> clear MSTA\n", __func__); +				temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); +				temp &= ~(I2CR_MSTA | I2CR_MTX); +				imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); +				i2c_imx_bus_busy(i2c_imx, 0); +				i2c_imx->stopped = 1; +			} else { +				/* +				 * For i2c master receiver repeat restart operation like: +				 * read -> repeat MSTA -> read/write +				 * The controller must set MTX before read the last byte in +				 * the first read operation, otherwise the first read cost +				 * one extra clock cycle. +				 */ +				temp = readb(i2c_imx->base + IMX_I2C_I2CR); +				temp |= I2CR_MTX; +				writeb(temp, i2c_imx->base + IMX_I2C_I2CR); +			}  		} else if (i == (msgs->len - 2)) {  			dev_dbg(&i2c_imx->adapter.dev,  				"<%s> set TXAK\n", __func__); @@ -508,7 +553,10 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)  			temp |= I2CR_TXAK;  			imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);  		} -		msgs->buf[i] = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR); +		if ((!i) && block_data) +			msgs->buf[0] = len; +		else +			msgs->buf[i] =  imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);  		dev_dbg(&i2c_imx->adapter.dev,  			"<%s> read byte: B%d=0x%X\n",  			__func__, i, msgs->buf[i]); @@ -521,6 +569,7 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,  {  	unsigned int i, temp;  	int result; +	bool is_lastmsg = false;  	struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter);  	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); @@ -532,6 +581,9 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,  	/* read/write data */  	for (i = 0; i < num; i++) { +		if (i == num - 1) +			is_lastmsg = true; +  		if (i) {  			dev_dbg(&i2c_imx->adapter.dev,  				"<%s> repeated start\n", __func__); @@ -562,7 +614,7 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,  			(temp & I2SR_RXAK ? 1 : 0));  #endif  		if (msgs[i].flags & I2C_M_RD) -			result = i2c_imx_read(i2c_imx, &msgs[i]); +			result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg);  		else  			result = i2c_imx_write(i2c_imx, &msgs[i]);  		if (result) @@ -581,7 +633,8 @@ fail0:  static u32 i2c_imx_func(struct i2c_adapter *adapter)  { -	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL +		| I2C_FUNC_SMBUS_READ_BLOCK_DATA;  }  static struct i2c_algorithm i2c_imx_algo = { @@ -589,7 +642,7 @@ static struct i2c_algorithm i2c_imx_algo = {  	.functionality	= i2c_imx_func,  }; -static int __init i2c_imx_probe(struct platform_device *pdev) +static int i2c_imx_probe(struct platform_device *pdev)  {  	const struct of_device_id *of_id = of_match_device(i2c_imx_dt_ids,  							   &pdev->dev); @@ -598,14 +651,13 @@ static int __init i2c_imx_probe(struct platform_device *pdev)  	struct imxi2c_platform_data *pdata = dev_get_platdata(&pdev->dev);  	void __iomem *base;  	int irq, ret; -	u32 bitrate;  	dev_dbg(&pdev->dev, "<%s>\n", __func__);  	irq = platform_get_irq(pdev, 0);  	if (irq < 0) {  		dev_err(&pdev->dev, "can't get irq number\n"); -		return -ENOENT; +		return irq;  	}  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -615,10 +667,8 @@ static int __init i2c_imx_probe(struct platform_device *pdev)  	i2c_imx = devm_kzalloc(&pdev->dev, sizeof(struct imx_i2c_struct),  				GFP_KERNEL); -	if (!i2c_imx) { -		dev_err(&pdev->dev, "can't allocate interface\n"); +	if (!i2c_imx)  		return -ENOMEM; -	}  	if (of_id)  		i2c_imx->hwdata = of_id->data; @@ -662,12 +712,11 @@ static int __init i2c_imx_probe(struct platform_device *pdev)  	i2c_set_adapdata(&i2c_imx->adapter, i2c_imx);  	/* Set up clock divider */ -	bitrate = IMX_I2C_BIT_RATE; +	i2c_imx->bitrate = IMX_I2C_BIT_RATE;  	ret = of_property_read_u32(pdev->dev.of_node, -				   "clock-frequency", &bitrate); +				   "clock-frequency", &i2c_imx->bitrate);  	if (ret < 0 && pdata && pdata->bitrate) -		bitrate = pdata->bitrate; -	i2c_imx_set_clk(i2c_imx, bitrate); +		i2c_imx->bitrate = pdata->bitrate;  	/* Set up chip registers to defaults */  	imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN, @@ -697,7 +746,7 @@ static int __init i2c_imx_probe(struct platform_device *pdev)  	return 0;   /* Return OK */  } -static int __exit i2c_imx_remove(struct platform_device *pdev) +static int i2c_imx_remove(struct platform_device *pdev)  {  	struct imx_i2c_struct *i2c_imx = platform_get_drvdata(pdev); @@ -715,7 +764,8 @@ static int __exit i2c_imx_remove(struct platform_device *pdev)  }  static struct platform_driver i2c_imx_driver = { -	.remove		= __exit_p(i2c_imx_remove), +	.probe = i2c_imx_probe, +	.remove = i2c_imx_remove,  	.driver	= {  		.name	= DRIVER_NAME,  		.owner	= THIS_MODULE, @@ -726,7 +776,7 @@ static struct platform_driver i2c_imx_driver = {  static int __init i2c_adap_imx_init(void)  { -	return platform_driver_probe(&i2c_imx_driver, i2c_imx_probe); +	return platform_driver_register(&i2c_imx_driver);  }  subsys_initcall(i2c_adap_imx_init); diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index dd24aa0424a..3d16c2f60a5 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -34,7 +34,6 @@  #include <linux/module.h>  #include <linux/delay.h>  #include <linux/slab.h> -#include <linux/init.h>  #include <linux/errno.h>  #include <linux/platform_device.h>  #include <linux/i2c.h> diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c index 8c38aaa7417..cf99dbf21fd 100644 --- a/drivers/i2c/busses/i2c-isch.c +++ b/drivers/i2c/busses/i2c-isch.c @@ -33,7 +33,6 @@  #include <linux/stddef.h>  #include <linux/ioport.h>  #include <linux/i2c.h> -#include <linux/init.h>  #include <linux/io.h>  #include <linux/acpi.h> @@ -275,7 +274,8 @@ static int smbus_sch_probe(struct platform_device *dev)  	if (!res)  		return -EBUSY; -	if (!request_region(res->start, resource_size(res), dev->name)) { +	if (!devm_request_region(&dev->dev, res->start, resource_size(res), +				 dev->name)) {  		dev_err(&dev->dev, "SMBus region 0x%x already in use!\n",  			sch_smba);  		return -EBUSY; @@ -294,7 +294,6 @@ static int smbus_sch_probe(struct platform_device *dev)  	retval = i2c_add_adapter(&sch_adapter);  	if (retval) {  		dev_err(&dev->dev, "Couldn't register adapter!\n"); -		release_region(res->start, resource_size(res));  		sch_smba = 0;  	} @@ -303,11 +302,8 @@ static int smbus_sch_probe(struct platform_device *dev)  static int smbus_sch_remove(struct platform_device *pdev)  { -	struct resource *res;  	if (sch_smba) {  		i2c_del_adapter(&sch_adapter); -		res = platform_get_resource(pdev, IORESOURCE_IO, 0); -		release_region(res->start, resource_size(res));  		sch_smba = 0;  	} diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c index 1672effbceb..984492553e9 100644 --- a/drivers/i2c/busses/i2c-ismt.c +++ b/drivers/i2c/busses/i2c-ismt.c @@ -62,7 +62,6 @@   */  #include <linux/module.h> -#include <linux/init.h>  #include <linux/pci.h>  #include <linux/kernel.h>  #include <linux/stddef.h> @@ -183,7 +182,7 @@ struct ismt_priv {  /**   * ismt_ids - PCI device IDs supported by this driver   */ -static DEFINE_PCI_DEVICE_TABLE(ismt_ids) = { +static const struct pci_device_id ismt_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT0) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT1) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMT) }, @@ -344,6 +343,7 @@ static int ismt_process_desc(const struct ismt_desc *desc,  			data->word = dma_buffer[0] | (dma_buffer[1] << 8);  			break;  		case I2C_SMBUS_BLOCK_DATA: +		case I2C_SMBUS_I2C_BLOCK_DATA:  			memcpy(&data->block[1], dma_buffer, desc->rxbytes);  			data->block[0] = desc->rxbytes;  			break; @@ -509,6 +509,41 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,  		}  		break; +	case I2C_SMBUS_I2C_BLOCK_DATA: +		/* Make sure the length is valid */ +		if (data->block[0] < 1) +			data->block[0] = 1; + +		if (data->block[0] > I2C_SMBUS_BLOCK_MAX) +			data->block[0] = I2C_SMBUS_BLOCK_MAX; + +		if (read_write == I2C_SMBUS_WRITE) { +			/* i2c Block Write */ +			dev_dbg(dev, "I2C_SMBUS_I2C_BLOCK_DATA:  WRITE\n"); +			dma_size = data->block[0] + 1; +			dma_direction = DMA_TO_DEVICE; +			desc->wr_len_cmd = dma_size; +			desc->control |= ISMT_DESC_I2C; +			priv->dma_buffer[0] = command; +			memcpy(&priv->dma_buffer[1], &data->block[1], dma_size); +		} else { +			/* i2c Block Read */ +			dev_dbg(dev, "I2C_SMBUS_I2C_BLOCK_DATA:  READ\n"); +			dma_size = data->block[0]; +			dma_direction = DMA_FROM_DEVICE; +			desc->rd_len = dma_size; +			desc->wr_len_cmd = command; +			desc->control |= (ISMT_DESC_I2C | ISMT_DESC_CWRL); +			/* +			 * Per the "Table 15-15. I2C Commands", +			 * in the External Design Specification (EDS), +			 * (Document Number: 508084, Revision: 2.0), +			 * the _rw bit must be 0 +			 */ +			desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(addr, 0); +		} +		break; +  	default:  		dev_err(dev, "Unsupported transaction %d\n",  			size); @@ -541,7 +576,7 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,  		desc->dptr_high = upper_32_bits(dma_addr);  	} -	INIT_COMPLETION(priv->cmp); +	reinit_completion(&priv->cmp);  	/* Add the descriptor */  	ismt_submit_desc(priv); @@ -582,6 +617,7 @@ static u32 ismt_func(struct i2c_adapter *adap)  	       I2C_FUNC_SMBUS_WORD_DATA		|  	       I2C_FUNC_SMBUS_PROC_CALL		|  	       I2C_FUNC_SMBUS_BLOCK_DATA	| +	       I2C_FUNC_SMBUS_I2C_BLOCK		|  	       I2C_FUNC_SMBUS_PEC;  } diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index b80c76888ca..6a32aa095f8 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -16,7 +16,8 @@  #include <linux/kernel.h>  #include <linux/module.h>  #include <linux/sched.h> -#include <linux/init.h> +#include <linux/of_address.h> +#include <linux/of_irq.h>  #include <linux/of_platform.h>  #include <linux/slab.h> @@ -114,7 +115,7 @@ static void mpc_i2c_fixup(struct mpc_i2c *i2c)  	for (k = 9; k; k--) {  		writeccr(i2c, 0);  		writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); -		udelay(delay_val); +		readb(i2c->base + MPC_I2C_DR);  		writeccr(i2c, CCR_MEN);  		udelay(delay_val << 1);  	} diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index d3e9cc3153a..9f4b775e2e3 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -17,6 +17,7 @@  #include <linux/interrupt.h>  #include <linux/mv643xx_i2c.h>  #include <linux/platform_device.h> +#include <linux/reset.h>  #include <linux/io.h>  #include <linux/of.h>  #include <linux/of_device.h> @@ -97,8 +98,6 @@ enum {  enum {  	MV64XXX_I2C_ACTION_INVALID,  	MV64XXX_I2C_ACTION_CONTINUE, -	MV64XXX_I2C_ACTION_OFFLOAD_SEND_START, -	MV64XXX_I2C_ACTION_SEND_START,  	MV64XXX_I2C_ACTION_SEND_RESTART,  	MV64XXX_I2C_ACTION_OFFLOAD_RESTART,  	MV64XXX_I2C_ACTION_SEND_ADDR_1, @@ -149,6 +148,8 @@ struct mv64xxx_i2c_data {  	bool			offload_enabled;  /* 5us delay in order to avoid repeated start timing violation */  	bool			errata_delay; +	struct reset_control	*rstc; +	bool			irq_clear_inverted;  };  static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = { @@ -177,11 +178,6 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,  {  	u32	dir = 0; -	drv_data->msg = msg; -	drv_data->byte_posn = 0; -	drv_data->bytes_left = msg->len; -	drv_data->aborting = 0; -	drv_data->rc = 0;  	drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK |  		MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN; @@ -204,11 +200,9 @@ static int mv64xxx_i2c_offload_msg(struct mv64xxx_i2c_data *drv_data)  	unsigned long ctrl_reg;  	struct i2c_msg *msg = drv_data->msgs; -	drv_data->msg = msg; -	drv_data->byte_posn = 0; -	drv_data->bytes_left = msg->len; -	drv_data->aborting = 0; -	drv_data->rc = 0; +	if (!drv_data->offload_enabled) +		return -EOPNOTSUPP; +  	/* Only regular transactions can be offloaded */  	if ((msg->flags & ~(I2C_M_TEN | I2C_M_RD)) != 0)  		return -EINVAL; @@ -417,6 +411,23 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)  	}  } +static void mv64xxx_i2c_send_start(struct mv64xxx_i2c_data *drv_data) +{ +	drv_data->msg = drv_data->msgs; +	drv_data->byte_posn = 0; +	drv_data->bytes_left = drv_data->msg->len; +	drv_data->aborting = 0; +	drv_data->rc = 0; + +	/* Can we offload this msg ? */ +	if (mv64xxx_i2c_offload_msg(drv_data) < 0) { +		/* No, switch to standard path */ +		mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs); +		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START, +			drv_data->reg_base + drv_data->reg_offsets.control); +	} +} +  static void  mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)  { @@ -433,15 +444,8 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)  		drv_data->msgs++;  		drv_data->num_msgs--; -		if (!(drv_data->offload_enabled && -				mv64xxx_i2c_offload_msg(drv_data))) { -			drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START; -			writel(drv_data->cntl_bits, -			drv_data->reg_base + drv_data->reg_offsets.control); +		mv64xxx_i2c_send_start(drv_data); -			/* Setup for the next message */ -			mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs); -		}  		if (drv_data->errata_delay)  			udelay(5); @@ -458,17 +462,6 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)  			drv_data->reg_base + drv_data->reg_offsets.control);  		break; -	case MV64XXX_I2C_ACTION_OFFLOAD_SEND_START: -		if (!mv64xxx_i2c_offload_msg(drv_data)) -			break; -		else -			drv_data->action = MV64XXX_I2C_ACTION_SEND_START; -		/* FALLTHRU */ -	case MV64XXX_I2C_ACTION_SEND_START: -		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START, -			drv_data->reg_base + drv_data->reg_offsets.control); -		break; -  	case MV64XXX_I2C_ACTION_SEND_ADDR_1:  		writel(drv_data->addr1,  			drv_data->reg_base + drv_data->reg_offsets.data); @@ -566,6 +559,11 @@ mv64xxx_i2c_intr(int irq, void *dev_id)  		status = readl(drv_data->reg_base + drv_data->reg_offsets.status);  		mv64xxx_i2c_fsm(drv_data, status);  		mv64xxx_i2c_do_action(drv_data); + +		if (drv_data->irq_clear_inverted) +			writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_IFLG, +			       drv_data->reg_base + drv_data->reg_offsets.control); +  		rc = IRQ_HANDLED;  	}  	spin_unlock_irqrestore(&drv_data->lock, flags); @@ -625,18 +623,12 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,  	unsigned long	flags;  	spin_lock_irqsave(&drv_data->lock, flags); -	if (drv_data->offload_enabled) { -		drv_data->action = MV64XXX_I2C_ACTION_OFFLOAD_SEND_START; -		drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND; -	} else { -		mv64xxx_i2c_prepare_for_io(drv_data, msg); -		drv_data->action = MV64XXX_I2C_ACTION_SEND_START; -		drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND; -	} +	drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND; +  	drv_data->send_stop = is_last;  	drv_data->block = 1; -	mv64xxx_i2c_do_action(drv_data); +	mv64xxx_i2c_send_start(drv_data);  	spin_unlock_irqrestore(&drv_data->lock, flags);  	mv64xxx_i2c_wait_for_completion(drv_data); @@ -689,9 +681,11 @@ static const struct i2c_algorithm mv64xxx_i2c_algo = {   *****************************************************************************   */  static const struct of_device_id mv64xxx_i2c_of_match_table[] = { -	{ .compatible = "allwinner,sun4i-i2c", .data = &mv64xxx_i2c_regs_sun4i}, +	{ .compatible = "allwinner,sun4i-a10-i2c", .data = &mv64xxx_i2c_regs_sun4i}, +	{ .compatible = "allwinner,sun6i-a31-i2c", .data = &mv64xxx_i2c_regs_sun4i},  	{ .compatible = "marvell,mv64xxx-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},  	{ .compatible = "marvell,mv78230-i2c", .data = &mv64xxx_i2c_regs_mv64xxx}, +	{ .compatible = "marvell,mv78230-a0-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},  	{}  };  MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table); @@ -763,6 +757,16 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,  	}  	drv_data->irq = irq_of_parse_and_map(np, 0); +	drv_data->rstc = devm_reset_control_get_optional(dev, NULL); +	if (IS_ERR(drv_data->rstc)) { +		if (PTR_ERR(drv_data->rstc) == -EPROBE_DEFER) { +			rc = -EPROBE_DEFER; +			goto out; +		} +	} else { +		reset_control_deassert(drv_data->rstc); +	} +  	/* Its not yet defined how timeouts will be specified in device tree.  	 * So hard code the value to 1 second.  	 */ @@ -783,6 +787,14 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,  		drv_data->errata_delay = true;  	} +	if (of_device_is_compatible(np, "marvell,mv78230-a0-i2c")) { +		drv_data->offload_enabled = false; +		drv_data->errata_delay = true; +	} + +	if (of_device_is_compatible(np, "allwinner,sun6i-a31-i2c")) +		drv_data->irq_clear_inverted = true; +  out:  	return rc;  #endif @@ -845,13 +857,13 @@ mv64xxx_i2c_probe(struct platform_device *pd)  	}  	if (drv_data->irq < 0) {  		rc = -ENXIO; -		goto exit_clk; +		goto exit_reset;  	}  	drv_data->adapter.dev.parent = &pd->dev;  	drv_data->adapter.algo = &mv64xxx_i2c_algo;  	drv_data->adapter.owner = THIS_MODULE; -	drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; +	drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED;  	drv_data->adapter.nr = pd->id;  	drv_data->adapter.dev.of_node = pd->dev.of_node;  	platform_set_drvdata(pd, drv_data); @@ -865,7 +877,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)  		dev_err(&drv_data->adapter.dev,  			"mv64xxx: Can't register intr handler irq%d: %d\n",  			drv_data->irq, rc); -		goto exit_clk; +		goto exit_reset;  	} else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) {  		dev_err(&drv_data->adapter.dev,  			"mv64xxx: Can't add i2c adapter, rc: %d\n", -rc); @@ -876,6 +888,9 @@ mv64xxx_i2c_probe(struct platform_device *pd)  exit_free_irq:  	free_irq(drv_data->irq, drv_data); +exit_reset: +	if (!IS_ERR_OR_NULL(drv_data->rstc)) +		reset_control_assert(drv_data->rstc);  exit_clk:  #if defined(CONFIG_HAVE_CLK)  	/* Not all platforms have a clk */ @@ -894,6 +909,8 @@ mv64xxx_i2c_remove(struct platform_device *dev)  	i2c_del_adapter(&drv_data->adapter);  	free_irq(drv_data->irq, drv_data); +	if (!IS_ERR_OR_NULL(drv_data->rstc)) +		reset_control_assert(drv_data->rstc);  #if defined(CONFIG_HAVE_CLK)  	/* Not all platforms have a clk */  	if (!IS_ERR(drv_data->clk)) { @@ -911,7 +928,7 @@ static struct platform_driver mv64xxx_i2c_driver = {  	.driver	= {  		.owner	= THIS_MODULE,  		.name	= MV64XXX_I2C_CTLR_NAME, -		.of_match_table = of_match_ptr(mv64xxx_i2c_of_match_table), +		.of_match_table = mv64xxx_i2c_of_match_table,  	},  }; diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index f4a01675fa7..7170fc89282 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -1,6 +1,7 @@  /*   * Freescale MXS I2C bus driver   * + * Copyright (C) 2012-2013 Marek Vasut <marex@denx.de>   * Copyright (C) 2011-2012 Wolfram Sang, Pengutronix e.K.   *   * based on a (non-working) driver which was: @@ -34,10 +35,12 @@  #define MXS_I2C_CTRL0		(0x00)  #define MXS_I2C_CTRL0_SET	(0x04) +#define MXS_I2C_CTRL0_CLR	(0x08)  #define MXS_I2C_CTRL0_SFTRST			0x80000000  #define MXS_I2C_CTRL0_RUN			0x20000000  #define MXS_I2C_CTRL0_SEND_NAK_ON_LAST		0x02000000 +#define MXS_I2C_CTRL0_PIO_MODE			0x01000000  #define MXS_I2C_CTRL0_RETAIN_CLOCK		0x00200000  #define MXS_I2C_CTRL0_POST_SEND_STOP		0x00100000  #define MXS_I2C_CTRL0_PRE_SEND_START		0x00080000 @@ -64,13 +67,13 @@  #define MXS_I2C_CTRL1_SLAVE_IRQ			0x01  #define MXS_I2C_STAT		(0x50) +#define MXS_I2C_STAT_GOT_A_NAK			0x10000000  #define MXS_I2C_STAT_BUS_BUSY			0x00000800  #define MXS_I2C_STAT_CLK_GEN_BUSY		0x00000400 -#define MXS_I2C_DATA		(0xa0) +#define MXS_I2C_DATA(i2c)	((i2c->dev_type == MXS_I2C_V1) ? 0x60 : 0xa0) -#define MXS_I2C_DEBUG0		(0xb0) -#define MXS_I2C_DEBUG0_CLR	(0xb8) +#define MXS_I2C_DEBUG0_CLR(i2c)	((i2c->dev_type == MXS_I2C_V1) ? 0x78 : 0xb8)  #define MXS_I2C_DEBUG0_DMAREQ	0x80000000 @@ -95,10 +98,17 @@  #define MXS_CMD_I2C_READ	(MXS_I2C_CTRL0_SEND_NAK_ON_LAST | \  				 MXS_I2C_CTRL0_MASTER_MODE) +enum mxs_i2c_devtype { +	MXS_I2C_UNKNOWN = 0, +	MXS_I2C_V1, +	MXS_I2C_V2, +}; +  /**   * struct mxs_i2c_dev - per device, private MXS-I2C data   *   * @dev: driver model device node + * @dev_type: distinguish i.MX23/i.MX28 features   * @regs: IO registers pointer   * @cmd_complete: completion object for transaction wait   * @cmd_err: error code for last transaction @@ -106,6 +116,7 @@   */  struct mxs_i2c_dev {  	struct device *dev; +	enum mxs_i2c_devtype dev_type;  	void __iomem *regs;  	struct completion cmd_complete;  	int cmd_err; @@ -291,48 +302,11 @@ write_init_pio_fail:  	return -EINVAL;  } -static int mxs_i2c_pio_wait_dmareq(struct mxs_i2c_dev *i2c) -{ -	unsigned long timeout = jiffies + msecs_to_jiffies(1000); - -	while (!(readl(i2c->regs + MXS_I2C_DEBUG0) & -		MXS_I2C_DEBUG0_DMAREQ)) { -		if (time_after(jiffies, timeout)) -			return -ETIMEDOUT; -		cond_resched(); -	} - -	return 0; -} - -static int mxs_i2c_pio_wait_cplt(struct mxs_i2c_dev *i2c, int last) +static int mxs_i2c_pio_wait_xfer_end(struct mxs_i2c_dev *i2c)  {  	unsigned long timeout = jiffies + msecs_to_jiffies(1000); -	/* -	 * We do not use interrupts in the PIO mode. Due to the -	 * maximum transfer length being 8 bytes in PIO mode, the -	 * overhead of interrupt would be too large and this would -	 * neglect the gain from using the PIO mode. -	 */ - -	while (!(readl(i2c->regs + MXS_I2C_CTRL1) & -		MXS_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ)) { -		if (time_after(jiffies, timeout)) -			return -ETIMEDOUT; -		cond_resched(); -	} - -	writel(MXS_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ, -		i2c->regs + MXS_I2C_CTRL1_CLR); - -	/* -	 * When ending a transfer with a stop, we have to wait for the bus to -	 * go idle before we report the transfer as completed. Otherwise the -	 * start of the next transfer may race with the end of the current one. -	 */ -	while (last && (readl(i2c->regs + MXS_I2C_STAT) & -			(MXS_I2C_STAT_BUS_BUSY | MXS_I2C_STAT_CLK_GEN_BUSY))) { +	while (readl(i2c->regs + MXS_I2C_CTRL0) & MXS_I2C_CTRL0_RUN) {  		if (time_after(jiffies, timeout))  			return -ETIMEDOUT;  		cond_resched(); @@ -370,106 +344,215 @@ static void mxs_i2c_pio_trigger_cmd(struct mxs_i2c_dev *i2c, u32 cmd)  	writel(reg, i2c->regs + MXS_I2C_CTRL0);  } +/* + * Start WRITE transaction on the I2C bus. By studying i.MX23 datasheet, + * CTRL0::PIO_MODE bit description clarifies the order in which the registers + * must be written during PIO mode operation. First, the CTRL0 register has + * to be programmed with all the necessary bits but the RUN bit. Then the + * payload has to be written into the DATA register. Finally, the transmission + * is executed by setting the RUN bit in CTRL0. + */ +static void mxs_i2c_pio_trigger_write_cmd(struct mxs_i2c_dev *i2c, u32 cmd, +					  u32 data) +{ +	writel(cmd, i2c->regs + MXS_I2C_CTRL0); + +	if (i2c->dev_type == MXS_I2C_V1) +		writel(MXS_I2C_CTRL0_PIO_MODE, i2c->regs + MXS_I2C_CTRL0_SET); + +	writel(data, i2c->regs + MXS_I2C_DATA(i2c)); +	writel(MXS_I2C_CTRL0_RUN, i2c->regs + MXS_I2C_CTRL0_SET); +} +  static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap,  			struct i2c_msg *msg, uint32_t flags)  {  	struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);  	uint32_t addr_data = msg->addr << 1;  	uint32_t data = 0; -	int i, shifts_left, ret; +	int i, ret, xlen = 0, xmit = 0; +	uint32_t start;  	/* Mute IRQs coming from this block. */  	writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_CLR); +	/* +	 * MX23 idea: +	 * - Enable CTRL0::PIO_MODE (1 << 24) +	 * - Enable CTRL1::ACK_MODE (1 << 27) +	 * +	 * WARNING! The MX23 is broken in some way, even if it claims +	 * to support PIO, when we try to transfer any amount of data +	 * that is not aligned to 4 bytes, the DMA engine will have +	 * bits in DEBUG1::DMA_BYTES_ENABLES still set even after the +	 * transfer. This in turn will mess up the next transfer as +	 * the block it emit one byte write onto the bus terminated +	 * with a NAK+STOP. A possible workaround is to reset the IP +	 * block after every PIO transmission, which might just work. +	 * +	 * NOTE: The CTRL0::PIO_MODE description is important, since +	 * it outlines how the PIO mode is really supposed to work. +	 */  	if (msg->flags & I2C_M_RD) { +		/* +		 * PIO READ transfer: +		 * +		 * This transfer MUST be limited to 4 bytes maximum. It is not +		 * possible to transfer more than four bytes via PIO, since we +		 * can not in any way make sure we can read the data from the +		 * DATA register fast enough. Besides, the RX FIFO is only four +		 * bytes deep, thus we can only really read up to four bytes at +		 * time. Finally, there is no bit indicating us that new data +		 * arrived at the FIFO and can thus be fetched from the DATA +		 * register. +		 */ +		BUG_ON(msg->len > 4); +  		addr_data |= I2C_SMBUS_READ;  		/* SELECT command. */ -		mxs_i2c_pio_trigger_cmd(i2c, MXS_CMD_I2C_SELECT); +		mxs_i2c_pio_trigger_write_cmd(i2c, MXS_CMD_I2C_SELECT, +					      addr_data); -		ret = mxs_i2c_pio_wait_dmareq(i2c); -		if (ret) -			return ret; - -		writel(addr_data, i2c->regs + MXS_I2C_DATA); -		writel(MXS_I2C_DEBUG0_DMAREQ, i2c->regs + MXS_I2C_DEBUG0_CLR); - -		ret = mxs_i2c_pio_wait_cplt(i2c, 0); -		if (ret) -			return ret; - -		if (mxs_i2c_pio_check_error_state(i2c)) +		ret = mxs_i2c_pio_wait_xfer_end(i2c); +		if (ret) { +			dev_err(i2c->dev, +				"PIO: Failed to send SELECT command!\n");  			goto cleanup; +		}  		/* READ command. */  		mxs_i2c_pio_trigger_cmd(i2c,  					MXS_CMD_I2C_READ | flags |  					MXS_I2C_CTRL0_XFER_COUNT(msg->len)); +		ret = mxs_i2c_pio_wait_xfer_end(i2c); +		if (ret) { +			dev_err(i2c->dev, +				"PIO: Failed to send SELECT command!\n"); +			goto cleanup; +		} + +		data = readl(i2c->regs + MXS_I2C_DATA(i2c));  		for (i = 0; i < msg->len; i++) { -			if ((i & 3) == 0) { -				ret = mxs_i2c_pio_wait_dmareq(i2c); -				if (ret) -					return ret; -				data = readl(i2c->regs + MXS_I2C_DATA); -				writel(MXS_I2C_DEBUG0_DMAREQ, -				       i2c->regs + MXS_I2C_DEBUG0_CLR); -			}  			msg->buf[i] = data & 0xff;  			data >>= 8;  		}  	} else { +		/* +		 * PIO WRITE transfer: +		 * +		 * The code below implements clock stretching to circumvent +		 * the possibility of kernel not being able to supply data +		 * fast enough. It is possible to transfer arbitrary amount +		 * of data using PIO write. +		 */  		addr_data |= I2C_SMBUS_WRITE; -		/* WRITE command. */ -		mxs_i2c_pio_trigger_cmd(i2c, -					MXS_CMD_I2C_WRITE | flags | -					MXS_I2C_CTRL0_XFER_COUNT(msg->len + 1)); -  		/*  		 * The LSB of data buffer is the first byte blasted across  		 * the bus. Higher order bytes follow. Thus the following  		 * filling schematic.  		 */ +  		data = addr_data << 24; + +		/* Start the transfer with START condition. */ +		start = MXS_I2C_CTRL0_PRE_SEND_START; + +		/* If the transfer is long, use clock stretching. */ +		if (msg->len > 3) +			start |= MXS_I2C_CTRL0_RETAIN_CLOCK; +  		for (i = 0; i < msg->len; i++) {  			data >>= 8;  			data |= (msg->buf[i] << 24); -			if ((i & 3) == 2) { -				ret = mxs_i2c_pio_wait_dmareq(i2c); -				if (ret) -					return ret; -				writel(data, i2c->regs + MXS_I2C_DATA); -				writel(MXS_I2C_DEBUG0_DMAREQ, -				       i2c->regs + MXS_I2C_DEBUG0_CLR); + +			xmit = 0; + +			/* This is the last transfer of the message. */ +			if (i + 1 == msg->len) { +				/* Add optional STOP flag. */ +				start |= flags; +				/* Remove RETAIN_CLOCK bit. */ +				start &= ~MXS_I2C_CTRL0_RETAIN_CLOCK; +				xmit = 1;  			} -		} -		shifts_left = 24 - (i & 3) * 8; -		if (shifts_left) { -			data >>= shifts_left; -			ret = mxs_i2c_pio_wait_dmareq(i2c); -			if (ret) -				return ret; -			writel(data, i2c->regs + MXS_I2C_DATA); +			/* Four bytes are ready in the "data" variable. */ +			if ((i & 3) == 2) +				xmit = 1; + +			/* Nothing interesting happened, continue stuffing. */ +			if (!xmit) +				continue; + +			/* +			 * Compute the size of the transfer and shift the +			 * data accordingly. +			 * +			 * i = (4k + 0) .... xlen = 2 +			 * i = (4k + 1) .... xlen = 3 +			 * i = (4k + 2) .... xlen = 4 +			 * i = (4k + 3) .... xlen = 1 +			 */ + +			if ((i % 4) == 3) +				xlen = 1; +			else +				xlen = (i % 4) + 2; + +			data >>= (4 - xlen) * 8; + +			dev_dbg(i2c->dev, +				"PIO: len=%i pos=%i total=%i [W%s%s%s]\n", +				xlen, i, msg->len, +				start & MXS_I2C_CTRL0_PRE_SEND_START ? "S" : "", +				start & MXS_I2C_CTRL0_POST_SEND_STOP ? "E" : "", +				start & MXS_I2C_CTRL0_RETAIN_CLOCK ? "C" : ""); +  			writel(MXS_I2C_DEBUG0_DMAREQ, -			       i2c->regs + MXS_I2C_DEBUG0_CLR); +			       i2c->regs + MXS_I2C_DEBUG0_CLR(i2c)); + +			mxs_i2c_pio_trigger_write_cmd(i2c, +				start | MXS_I2C_CTRL0_MASTER_MODE | +				MXS_I2C_CTRL0_DIRECTION | +				MXS_I2C_CTRL0_XFER_COUNT(xlen), data); + +			/* The START condition is sent only once. */ +			start &= ~MXS_I2C_CTRL0_PRE_SEND_START; + +			/* Wait for the end of the transfer. */ +			ret = mxs_i2c_pio_wait_xfer_end(i2c); +			if (ret) { +				dev_err(i2c->dev, +					"PIO: Failed to finish WRITE cmd!\n"); +				break; +			} + +			/* Check NAK here. */ +			ret = readl(i2c->regs + MXS_I2C_STAT) & +				    MXS_I2C_STAT_GOT_A_NAK; +			if (ret) { +				ret = -ENXIO; +				goto cleanup; +			}  		}  	} -	ret = mxs_i2c_pio_wait_cplt(i2c, flags & MXS_I2C_CTRL0_POST_SEND_STOP); -	if (ret) -		return ret; -  	/* make sure we capture any occurred error into cmd_err */ -	mxs_i2c_pio_check_error_state(i2c); +	ret = mxs_i2c_pio_check_error_state(i2c);  cleanup:  	/* Clear any dangling IRQs and re-enable interrupts. */  	writel(MXS_I2C_IRQ_MASK, i2c->regs + MXS_I2C_CTRL1_CLR);  	writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET); -	return 0; +	/* Clear the PIO_MODE on i.MX23 */ +	if (i2c->dev_type == MXS_I2C_V1) +		writel(MXS_I2C_CTRL0_PIO_MODE, i2c->regs + MXS_I2C_CTRL0_CLR); + +	return ret;  }  /* @@ -479,8 +562,9 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,  				int stop)  {  	struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap); -	int ret, err; +	int ret;  	int flags; +	int use_pio = 0;  	flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0; @@ -491,21 +575,23 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,  		return -EINVAL;  	/* -	 * The current boundary to select between PIO/DMA transfer method -	 * is set to 8 bytes, transfers shorter than 8 bytes are transfered -	 * using PIO mode while longer transfers use DMA. The 8 byte border is -	 * based on this empirical measurement and a lot of previous frobbing. +	 * The MX28 I2C IP block can only do PIO READ for transfer of to up +	 * 4 bytes of length. The write transfer is not limited as it can use +	 * clock stretching to avoid FIFO underruns.  	 */ +	if ((msg->flags & I2C_M_RD) && (msg->len <= 4)) +		use_pio = 1; +	if (!(msg->flags & I2C_M_RD) && (msg->len < 7)) +		use_pio = 1; +  	i2c->cmd_err = 0; -	if (0) {	/* disable PIO mode until a proper fix is made */ +	if (use_pio) {  		ret = mxs_i2c_pio_setup_xfer(adap, msg, flags); -		if (ret) { -			err = mxs_i2c_reset(i2c); -			if (err) -				return err; -		} +		/* No need to reset the block if NAK was received. */ +		if (ret && (ret != -ENXIO)) +			mxs_i2c_reset(i2c);  	} else { -		INIT_COMPLETION(i2c->cmd_complete); +		reinit_completion(&i2c->cmd_complete);  		ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);  		if (ret)  			return ret; @@ -514,9 +600,11 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,  						msecs_to_jiffies(1000));  		if (ret == 0)  			goto timeout; + +		ret = i2c->cmd_err;  	} -	if (i2c->cmd_err == -ENXIO) { +	if (ret == -ENXIO) {  		/*  		 * If the transfer fails with a NAK from the slave the  		 * controller halts until it gets told to return to idle state. @@ -525,7 +613,19 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,  		       i2c->regs + MXS_I2C_CTRL1_SET);  	} -	ret = i2c->cmd_err; +	/* +	 * WARNING! +	 * The i.MX23 is strange. After each and every operation, it's I2C IP +	 * block must be reset, otherwise the IP block will misbehave. This can +	 * be observed on the bus by the block sending out one single byte onto +	 * the bus. In case such an error happens, bit 27 will be set in the +	 * DEBUG0 register. This bit is not documented in the i.MX23 datasheet +	 * and is marked as "TBD" instead. To reset this bit to a correct state, +	 * reset the whole block. Since the block reset does not take long, do +	 * reset the block after every transfer to play safe. +	 */ +	if (i2c->dev_type == MXS_I2C_V1) +		mxs_i2c_reset(i2c);  	dev_dbg(i2c->dev, "Done with err=%d\n", ret); @@ -680,32 +780,51 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)  	return 0;  } +static struct platform_device_id mxs_i2c_devtype[] = { +	{ +		.name = "imx23-i2c", +		.driver_data = MXS_I2C_V1, +	}, { +		.name = "imx28-i2c", +		.driver_data = MXS_I2C_V2, +	}, { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, mxs_i2c_devtype); + +static const struct of_device_id mxs_i2c_dt_ids[] = { +	{ .compatible = "fsl,imx23-i2c", .data = &mxs_i2c_devtype[0], }, +	{ .compatible = "fsl,imx28-i2c", .data = &mxs_i2c_devtype[1], }, +	{ /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, mxs_i2c_dt_ids); +  static int mxs_i2c_probe(struct platform_device *pdev)  { +	const struct of_device_id *of_id = +				of_match_device(mxs_i2c_dt_ids, &pdev->dev);  	struct device *dev = &pdev->dev;  	struct mxs_i2c_dev *i2c;  	struct i2c_adapter *adap;  	struct resource *res; -	resource_size_t res_size;  	int err, irq;  	i2c = devm_kzalloc(dev, sizeof(struct mxs_i2c_dev), GFP_KERNEL);  	if (!i2c)  		return -ENOMEM; -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	irq = platform_get_irq(pdev, 0); - -	if (!res || irq < 0) -		return -ENOENT; +	if (of_id) { +		const struct platform_device_id *device_id = of_id->data; +		i2c->dev_type = device_id->driver_data; +	} -	res_size = resource_size(res); -	if (!devm_request_mem_region(dev, res->start, res_size, res->name)) -		return -EBUSY; +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	i2c->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(i2c->regs)) +		return PTR_ERR(i2c->regs); -	i2c->regs = devm_ioremap_nocache(dev, res->start, res_size); -	if (!i2c->regs) -		return -EBUSY; +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) +		return irq;  	err = devm_request_irq(dev, irq, mxs_i2c_isr, 0, dev_name(dev), i2c);  	if (err) @@ -768,24 +887,19 @@ static int mxs_i2c_remove(struct platform_device *pdev)  	return 0;  } -static const struct of_device_id mxs_i2c_dt_ids[] = { -	{ .compatible = "fsl,imx28-i2c", }, -	{ /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, mxs_i2c_dt_ids); -  static struct platform_driver mxs_i2c_driver = {  	.driver = {  		   .name = DRIVER_NAME,  		   .owner = THIS_MODULE,  		   .of_match_table = mxs_i2c_dt_ids,  		   }, +	.probe = mxs_i2c_probe,  	.remove = mxs_i2c_remove,  };  static int __init mxs_i2c_init(void)  { -	return platform_driver_probe(&mxs_i2c_driver, mxs_i2c_probe); +	return platform_driver_register(&mxs_i2c_driver);  }  subsys_initcall(mxs_i2c_init); @@ -795,6 +909,7 @@ static void __exit mxs_i2c_exit(void)  }  module_exit(mxs_i2c_exit); +MODULE_AUTHOR("Marek Vasut <marex@denx.de>");  MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");  MODULE_DESCRIPTION("MXS I2C Bus Driver");  MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-nforce2-s4985.c b/drivers/i2c/busses/i2c-nforce2-s4985.c index 2ca268d6140..b170bdffb5d 100644 --- a/drivers/i2c/busses/i2c-nforce2-s4985.c +++ b/drivers/i2c/busses/i2c-nforce2-s4985.c @@ -1,7 +1,7 @@  /*   * i2c-nforce2-s4985.c - i2c-nforce2 extras for the Tyan S4985 motherboard   * - * Copyright (C) 2008 Jean Delvare <khali@linux-fr.org> + * Copyright (C) 2008 Jean Delvare <jdelvare@suse.de>   *   * 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 @@ -245,7 +245,7 @@ static void __exit nforce2_s4985_exit(void)  		       "Physical bus restoration failed\n");  } -MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); +MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");  MODULE_DESCRIPTION("S4985 SMBus multiplexing");  MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index ac88f4000cc..ee3a76c7ae9 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -51,7 +51,6 @@  #include <linux/kernel.h>  #include <linux/stddef.h>  #include <linux/ioport.h> -#include <linux/init.h>  #include <linux/i2c.h>  #include <linux/delay.h>  #include <linux/dmi.h> @@ -307,7 +306,7 @@ static struct i2c_algorithm smbus_algorithm = {  }; -static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = { +static const struct pci_device_id nforce2_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) },  	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS) },  	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) }, diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index 8bf9ac01301..0e55d85fd4e 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c @@ -22,7 +22,6 @@  #include <linux/clk.h>  #include <linux/io.h>  #include <linux/pm_runtime.h> -#include <linux/platform_data/i2c-nomadik.h>  #include <linux/of.h>  #include <linux/pinctrl/consumer.h> @@ -104,6 +103,13 @@  /* maximum threshold value */  #define MAX_I2C_FIFO_THRESHOLD	15 +enum i2c_freq_mode { +	I2C_FREQ_MODE_STANDARD,		/* up to 100 Kb/s */ +	I2C_FREQ_MODE_FAST,		/* up to 400 Kb/s */ +	I2C_FREQ_MODE_HIGH_SPEED,	/* up to 3.4 Mb/s */ +	I2C_FREQ_MODE_FAST_PLUS,	/* up to 1 Mb/s */ +}; +  /**   * struct i2c_vendor_data - per-vendor variations   * @has_mtdws: variant has the MTDWS bit @@ -152,12 +158,15 @@ struct i2c_nmk_client {   * @irq: interrupt line for the controller.   * @virtbase: virtual io memory area.   * @clk: hardware i2c block clock. - * @cfg: machine provided controller configuration.   * @cli: holder of client specific data. + * @clk_freq: clock frequency for the operation mode + * @tft: Tx FIFO Threshold in bytes + * @rft: Rx FIFO Threshold in bytes + * @timeout Slave response timeout (ms) + * @sm: speed mode   * @stop: stop condition.   * @xfer_complete: acknowledge completion for a I2C message.   * @result: controller propogated result. - * @busy: Busy doing transfer.   */  struct nmk_i2c_dev {  	struct i2c_vendor_data		*vendor; @@ -166,12 +175,15 @@ struct nmk_i2c_dev {  	int				irq;  	void __iomem			*virtbase;  	struct clk			*clk; -	struct nmk_i2c_controller	cfg;  	struct i2c_nmk_client		cli; +	u32				clk_freq; +	unsigned char			tft; +	unsigned char			rft; +	int				timeout; +	enum i2c_freq_mode		sm;  	int				stop;  	struct completion		xfer_complete;  	int				result; -	bool				busy;  };  /* controller's abort causes */ @@ -340,6 +352,8 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)  {  	u32 brcr1, brcr2;  	u32 i2c_clk, div; +	u32 ns; +	u16 slsu;  	writel(0x0, dev->virtbase + I2C_CR);  	writel(0x0, dev->virtbase + I2C_HSMCR); @@ -347,25 +361,45 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)  	writel(0x0, dev->virtbase + I2C_RFTR);  	writel(0x0, dev->virtbase + I2C_DMAR); +	i2c_clk = clk_get_rate(dev->clk); +  	/*  	 * set the slsu:  	 *  	 * slsu defines the data setup time after SCL clock -	 * stretching in terms of i2c clk cycles. The -	 * needed setup time for the three modes are 250ns, -	 * 100ns, 10ns respectively thus leading to the values -	 * of 14, 6, 2 for a 48 MHz i2c clk. +	 * stretching in terms of i2c clk cycles + 1 (zero means +	 * "wait one cycle"), the needed setup time for the three +	 * modes are 250ns, 100ns, 10ns respectively. +	 * +	 * As the time for one cycle T in nanoseconds is +	 * T = (1/f) * 1000000000 => +	 * slsu = cycles / (1000000000 / f) + 1  	 */ -	writel(dev->cfg.slsu << 16, dev->virtbase + I2C_SCR); +	ns = DIV_ROUND_UP_ULL(1000000000ULL, i2c_clk); +	switch (dev->sm) { +	case I2C_FREQ_MODE_FAST: +	case I2C_FREQ_MODE_FAST_PLUS: +		slsu = DIV_ROUND_UP(100, ns); /* Fast */ +		break; +	case I2C_FREQ_MODE_HIGH_SPEED: +		slsu = DIV_ROUND_UP(10, ns); /* High */ +		break; +	case I2C_FREQ_MODE_STANDARD: +	default: +		slsu = DIV_ROUND_UP(250, ns); /* Standard */ +		break; +	} +	slsu += 1; -	i2c_clk = clk_get_rate(dev->clk); +	dev_dbg(&dev->adev->dev, "calculated SLSU = %04x\n", slsu); +	writel(slsu << 16, dev->virtbase + I2C_SCR);  	/*  	 * The spec says, in case of std. mode the divider is  	 * 2 whereas it is 3 for fast and fastplus mode of  	 * operation. TODO - high speed support.  	 */ -	div = (dev->cfg.clk_freq > 100000) ? 3 : 2; +	div = (dev->clk_freq > 100000) ? 3 : 2;  	/*  	 * generate the mask for baud rate counters. The controller @@ -375,7 +409,7 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)  	 * so set brcr1 to 0.  	 */  	brcr1 = 0 << 16; -	brcr2 = (i2c_clk/(dev->cfg.clk_freq * div)) & 0xffff; +	brcr2 = (i2c_clk/(dev->clk_freq * div)) & 0xffff;  	/* set the baud rate counter register */  	writel((brcr1 | brcr2), dev->virtbase + I2C_BRCR); @@ -386,7 +420,7 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)  	 * TODO - support for fast mode plus (up to 1Mb/s)  	 * and high speed (up to 3.4 Mb/s)  	 */ -	if (dev->cfg.sm > I2C_FREQ_MODE_FAST) { +	if (dev->sm > I2C_FREQ_MODE_FAST) {  		dev_err(&dev->adev->dev,  			"do not support this mode defaulting to std. mode\n");  		brcr2 = i2c_clk/(100000 * 2) & 0xffff; @@ -394,11 +428,11 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)  		writel(I2C_FREQ_MODE_STANDARD << 4,  				dev->virtbase + I2C_CR);  	} -	writel(dev->cfg.sm << 4, dev->virtbase + I2C_CR); +	writel(dev->sm << 4, dev->virtbase + I2C_CR);  	/* set the Tx and Rx FIFO threshold */ -	writel(dev->cfg.tft, dev->virtbase + I2C_TFTR); -	writel(dev->cfg.rft, dev->virtbase + I2C_RFTR); +	writel(dev->tft, dev->virtbase + I2C_TFTR); +	writel(dev->rft, dev->virtbase + I2C_RFTR);  }  /** @@ -630,28 +664,13 @@ static int nmk_i2c_xfer_one(struct nmk_i2c_dev *dev, u16 flags)  static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,  		struct i2c_msg msgs[], int num_msgs)  { -	int status; +	int status = 0;  	int i;  	struct nmk_i2c_dev *dev = i2c_get_adapdata(i2c_adap);  	int j; -	dev->busy = true; -  	pm_runtime_get_sync(&dev->adev->dev); -	status = clk_prepare_enable(dev->clk); -	if (status) { -		dev_err(&dev->adev->dev, "can't prepare_enable clock\n"); -		goto out_clk; -	} - -	/* Optionaly enable pins to be muxed in and configured */ -	pinctrl_pm_select_default_state(&dev->adev->dev); - -	status = init_hw(dev); -	if (status) -		goto out; -  	/* Attempt three times to send the message queue */  	for (j = 0; j < 3; j++) {  		/* setup the i2c controller */ @@ -672,16 +691,8 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,  			break;  	} -out: -	clk_disable_unprepare(dev->clk); -out_clk: -	/* Optionally let pins go into idle state */ -	pinctrl_pm_select_idle_state(&dev->adev->dev); -  	pm_runtime_put_sync(&dev->adev->dev); -	dev->busy = false; -  	/* return the no. messages processed */  	if (status)  		return status; @@ -865,43 +876,65 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)  	return IRQ_HANDLED;  } +#ifdef CONFIG_PM_SLEEP +static int nmk_i2c_suspend_late(struct device *dev) +{ +	int ret; + +	ret = pm_runtime_force_suspend(dev); +	if (ret) +		return ret; + +	pinctrl_pm_select_sleep_state(dev); +	return 0; +} + +static int nmk_i2c_resume_early(struct device *dev) +{ +	return pm_runtime_force_resume(dev); +} +#endif  #ifdef CONFIG_PM -static int nmk_i2c_suspend(struct device *dev) +static int nmk_i2c_runtime_suspend(struct device *dev)  {  	struct amba_device *adev = to_amba_device(dev);  	struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev); -	if (nmk_i2c->busy) -		return -EBUSY; - -	pinctrl_pm_select_sleep_state(dev); - +	clk_disable_unprepare(nmk_i2c->clk); +	pinctrl_pm_select_idle_state(dev);  	return 0;  } -static int nmk_i2c_resume(struct device *dev) +static int nmk_i2c_runtime_resume(struct device *dev)  { -	/* First go to the default state */ +	struct amba_device *adev = to_amba_device(dev); +	struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev); +	int ret; + +	ret = clk_prepare_enable(nmk_i2c->clk); +	if (ret) { +		dev_err(dev, "can't prepare_enable clock\n"); +		return ret; +	} +  	pinctrl_pm_select_default_state(dev); -	/* Then let's idle the pins until the next transfer happens */ -	pinctrl_pm_select_idle_state(dev); -	return 0; +	ret = init_hw(nmk_i2c); +	if (ret) { +		clk_disable_unprepare(nmk_i2c->clk); +		pinctrl_pm_select_idle_state(dev); +	} + +	return ret;  } -#else -#define nmk_i2c_suspend	NULL -#define nmk_i2c_resume	NULL  #endif -/* - * We use noirq so that we suspend late and resume before the wakeup interrupt - * to ensure that we do the !pm_runtime_suspended() check in resume before - * there has been a regular pm runtime resume (via pm_runtime_get_sync()). - */  static const struct dev_pm_ops nmk_i2c_pm = { -	.suspend_noirq	= nmk_i2c_suspend, -	.resume_noirq	= nmk_i2c_resume, +	SET_LATE_SYSTEM_SLEEP_PM_OPS(nmk_i2c_suspend_late, nmk_i2c_resume_early) +	SET_PM_RUNTIME_PM_OPS(nmk_i2c_runtime_suspend, +			nmk_i2c_runtime_resume, +			NULL)  };  static unsigned int nmk_i2c_functionality(struct i2c_adapter *adap) @@ -914,124 +947,98 @@ static const struct i2c_algorithm nmk_i2c_algo = {  	.functionality	= nmk_i2c_functionality  }; -static struct nmk_i2c_controller u8500_i2c = { -	/* -	 * Slave data setup time; 250ns, 100ns, and 10ns, which -	 * is 14, 6 and 2 respectively for a 48Mhz i2c clock. -	 */ -	.slsu           = 0xe, -	.tft            = 1,      /* Tx FIFO threshold */ -	.rft            = 8,      /* Rx FIFO threshold */ -	.clk_freq       = 400000, /* fast mode operation */ -	.timeout        = 200,    /* Slave response timeout(ms) */ -	.sm             = I2C_FREQ_MODE_FAST, -}; -  static void nmk_i2c_of_probe(struct device_node *np, -			struct nmk_i2c_controller *pdata) +			     struct nmk_i2c_dev *nmk)  { -	of_property_read_u32(np, "clock-frequency", &pdata->clk_freq); +	/* Default to 100 kHz if no frequency is given in the node */ +	if (of_property_read_u32(np, "clock-frequency", &nmk->clk_freq)) +		nmk->clk_freq = 100000;  	/* This driver only supports 'standard' and 'fast' modes of operation. */ -	if (pdata->clk_freq <= 100000) -		pdata->sm = I2C_FREQ_MODE_STANDARD; +	if (nmk->clk_freq <= 100000) +		nmk->sm = I2C_FREQ_MODE_STANDARD;  	else -		pdata->sm = I2C_FREQ_MODE_FAST; +		nmk->sm = I2C_FREQ_MODE_FAST; +	nmk->tft = 1; /* Tx FIFO threshold */ +	nmk->rft = 8; /* Rx FIFO threshold */ +	nmk->timeout = 200; /* Slave response timeout(ms) */  }  static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)  {  	int ret = 0; -	struct nmk_i2c_controller *pdata = dev_get_platdata(&adev->dev);  	struct device_node *np = adev->dev.of_node;  	struct nmk_i2c_dev	*dev;  	struct i2c_adapter *adap;  	struct i2c_vendor_data *vendor = id->data;  	u32 max_fifo_threshold = (vendor->fifodepth / 2) - 1; -	if (!pdata) { -		if (np) { -			pdata = devm_kzalloc(&adev->dev, sizeof(*pdata), GFP_KERNEL); -			if (!pdata) { -				ret = -ENOMEM; -				goto err_no_mem; -			} -			/* Provide the default configuration as a base. */ -			memcpy(pdata, &u8500_i2c, sizeof(struct nmk_i2c_controller)); -			nmk_i2c_of_probe(np, pdata); -		} else -			/* No i2c configuration found, using the default. */ -			pdata = &u8500_i2c; +	dev = devm_kzalloc(&adev->dev, sizeof(struct nmk_i2c_dev), GFP_KERNEL); +	if (!dev) { +		dev_err(&adev->dev, "cannot allocate memory\n"); +		ret = -ENOMEM; +		goto err_no_mem;  	} +	dev->vendor = vendor; +	dev->adev = adev; +	nmk_i2c_of_probe(np, dev); -	if (pdata->tft > max_fifo_threshold) { +	if (dev->tft > max_fifo_threshold) {  		dev_warn(&adev->dev, "requested TX FIFO threshold %u, adjusted down to %u\n", -			pdata->tft, max_fifo_threshold); -		pdata->tft = max_fifo_threshold; +			 dev->tft, max_fifo_threshold); +		dev->tft = max_fifo_threshold;  	} -	if (pdata->rft > max_fifo_threshold) { +	if (dev->rft > max_fifo_threshold) {  		dev_warn(&adev->dev, "requested RX FIFO threshold %u, adjusted down to %u\n", -			pdata->rft, max_fifo_threshold); -		pdata->rft = max_fifo_threshold; +			dev->rft, max_fifo_threshold); +		dev->rft = max_fifo_threshold;  	} -	dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL); -	if (!dev) { -		dev_err(&adev->dev, "cannot allocate memory\n"); -		ret = -ENOMEM; -		goto err_no_mem; -	} -	dev->vendor = vendor; -	dev->busy = false; -	dev->adev = adev;  	amba_set_drvdata(adev, dev); -	/* Select default pin state */ -	pinctrl_pm_select_default_state(&adev->dev); -	/* If possible, let's go to idle until the first transfer */ -	pinctrl_pm_select_idle_state(&adev->dev); - -	dev->virtbase = ioremap(adev->res.start, resource_size(&adev->res)); +	dev->virtbase = devm_ioremap(&adev->dev, adev->res.start, +				resource_size(&adev->res));  	if (!dev->virtbase) {  		ret = -ENOMEM; -		goto err_no_ioremap; +		goto err_no_mem;  	}  	dev->irq = adev->irq[0]; -	ret = request_irq(dev->irq, i2c_irq_handler, 0, +	ret = devm_request_irq(&adev->dev, dev->irq, i2c_irq_handler, 0,  				DRIVER_NAME, dev);  	if (ret) {  		dev_err(&adev->dev, "cannot claim the irq %d\n", dev->irq); -		goto err_irq; +		goto err_no_mem;  	}  	pm_suspend_ignore_children(&adev->dev, true); -	dev->clk = clk_get(&adev->dev, NULL); +	dev->clk = devm_clk_get(&adev->dev, NULL);  	if (IS_ERR(dev->clk)) {  		dev_err(&adev->dev, "could not get i2c clock\n");  		ret = PTR_ERR(dev->clk); -		goto err_no_clk; +		goto err_no_mem; +	} + +	ret = clk_prepare_enable(dev->clk); +	if (ret) { +		dev_err(&adev->dev, "can't prepare_enable clock\n"); +		goto err_no_mem;  	} +	init_hw(dev); +  	adap = &dev->adap;  	adap->dev.of_node = np;  	adap->dev.parent = &adev->dev;  	adap->owner	= THIS_MODULE; -	adap->class	= I2C_CLASS_HWMON | I2C_CLASS_SPD; +	adap->class	= I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED;  	adap->algo	= &nmk_i2c_algo; -	adap->timeout	= msecs_to_jiffies(pdata->timeout); +	adap->timeout	= msecs_to_jiffies(dev->timeout);  	snprintf(adap->name, sizeof(adap->name),  		 "Nomadik I2C at %pR", &adev->res); -	/* fetch the controller configuration from machine */ -	dev->cfg.clk_freq = pdata->clk_freq; -	dev->cfg.slsu	= pdata->slsu; -	dev->cfg.tft	= pdata->tft; -	dev->cfg.rft	= pdata->rft; -	dev->cfg.sm	= pdata->sm; -  	i2c_set_adapdata(adap, dev);  	dev_info(&adev->dev, @@ -1041,21 +1048,15 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)  	ret = i2c_add_adapter(adap);  	if (ret) {  		dev_err(&adev->dev, "failed to add adapter\n"); -		goto err_add_adap; +		goto err_no_adap;  	}  	pm_runtime_put(&adev->dev);  	return 0; - err_add_adap: -	clk_put(dev->clk); - err_no_clk: -	free_irq(dev->irq, dev); - err_irq: -	iounmap(dev->virtbase); - err_no_ioremap: -	kfree(dev); + err_no_adap: +	clk_disable_unprepare(dev->clk);   err_no_mem:  	return ret; @@ -1072,13 +1073,9 @@ static int nmk_i2c_remove(struct amba_device *adev)  	clear_all_interrupts(dev);  	/* disable the controller */  	i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE); -	free_irq(dev->irq, dev); -	iounmap(dev->virtbase); +	clk_disable_unprepare(dev->clk);  	if (res)  		release_mem_region(res->start, resource_size(res)); -	clk_put(dev->clk); -	pm_runtime_disable(&adev->dev); -	kfree(dev);  	return 0;  } diff --git a/drivers/i2c/busses/i2c-nuc900.c b/drivers/i2c/busses/i2c-nuc900.c deleted file mode 100644 index 36394d737fa..00000000000 --- a/drivers/i2c/busses/i2c-nuc900.c +++ /dev/null @@ -1,709 +0,0 @@ -/* - * linux/drivers/i2c/busses/i2c-nuc900.c - * - * Copyright (c) 2010 Nuvoton technology corporation. - * - * This driver based on S3C2410 I2C driver of Ben Dooks <ben-Y5A6D6n0/KfQXOPxS62xeg@public.gmane.org>. - * Written by Wan ZongShun <mcuos.com-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> - * - * 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;version 2 of the License. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> - -#include <linux/i2c.h> -#include <linux/init.h> -#include <linux/time.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/err.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/cpufreq.h> -#include <linux/slab.h> -#include <linux/io.h> - -#include <mach/mfp.h> -#include <linux/platform_data/i2c-nuc900.h> - -/* nuc900 i2c registers offset */ - -#define CSR		0x00 -#define DIVIDER		0x04 -#define CMDR		0x08 -#define SWR		0x0C -#define RXR		0x10 -#define TXR		0x14 - -/* nuc900 i2c CSR register bits */ - -#define IRQEN		0x003 -#define I2CBUSY		0x400 -#define I2CSTART	0x018 -#define IRQFLAG		0x004 -#define ARBIT_LOST	0x200 -#define SLAVE_ACK	0x800 - -/* nuc900 i2c CMDR register bits */ - -#define I2C_CMD_START	0x10 -#define I2C_CMD_STOP	0x08 -#define I2C_CMD_READ	0x04 -#define I2C_CMD_WRITE	0x02 -#define I2C_CMD_NACK	0x01 - -/* i2c controller state */ - -enum nuc900_i2c_state { -	STATE_IDLE, -	STATE_START, -	STATE_READ, -	STATE_WRITE, -	STATE_STOP -}; - -/* i2c controller private data */ - -struct nuc900_i2c { -	spinlock_t		lock; -	wait_queue_head_t	wait; - -	struct i2c_msg		*msg; -	unsigned int		msg_num; -	unsigned int		msg_idx; -	unsigned int		msg_ptr; -	unsigned int		irq; - -	enum nuc900_i2c_state	state; - -	void __iomem		*regs; -	struct clk		*clk; -	struct device		*dev; -	struct resource		*ioarea; -	struct i2c_adapter	adap; -}; - -/* nuc900_i2c_master_complete - * - * complete the message and wake up the caller, using the given return code, - * or zero to mean ok. -*/ - -static inline void nuc900_i2c_master_complete(struct nuc900_i2c *i2c, int ret) -{ -	dev_dbg(i2c->dev, "master_complete %d\n", ret); - -	i2c->msg_ptr = 0; -	i2c->msg = NULL; -	i2c->msg_idx++; -	i2c->msg_num = 0; -	if (ret) -		i2c->msg_idx = ret; - -	wake_up(&i2c->wait); -} - -/* irq enable/disable functions */ - -static inline void nuc900_i2c_disable_irq(struct nuc900_i2c *i2c) -{ -	unsigned long tmp; - -	tmp = readl(i2c->regs + CSR); -	writel(tmp & ~IRQEN, i2c->regs + CSR); -} - -static inline void nuc900_i2c_enable_irq(struct nuc900_i2c *i2c) -{ -	unsigned long tmp; - -	tmp = readl(i2c->regs + CSR); -	writel(tmp | IRQEN, i2c->regs + CSR); -} - - -/* nuc900_i2c_message_start - * - * put the start of a message onto the bus -*/ - -static void nuc900_i2c_message_start(struct nuc900_i2c *i2c, -				      struct i2c_msg *msg) -{ -	unsigned int addr = (msg->addr & 0x7f) << 1; - -	if (msg->flags & I2C_M_RD) -		addr |= 0x1; -	writel(addr & 0xff, i2c->regs + TXR); -	writel(I2C_CMD_START | I2C_CMD_WRITE, i2c->regs + CMDR); -} - -static inline void nuc900_i2c_stop(struct nuc900_i2c *i2c, int ret) -{ - -	dev_dbg(i2c->dev, "STOP\n"); - -	/* stop the transfer */ -	i2c->state = STATE_STOP; -	writel(I2C_CMD_STOP, i2c->regs + CMDR); - -	nuc900_i2c_master_complete(i2c, ret); -	nuc900_i2c_disable_irq(i2c); -} - -/* helper functions to determine the current state in the set of - * messages we are sending -*/ - -/* is_lastmsg() - * - * returns TRUE if the current message is the last in the set -*/ - -static inline int is_lastmsg(struct nuc900_i2c *i2c) -{ -	return i2c->msg_idx >= (i2c->msg_num - 1); -} - -/* is_msglast - * - * returns TRUE if we this is the last byte in the current message -*/ - -static inline int is_msglast(struct nuc900_i2c *i2c) -{ -	return i2c->msg_ptr == i2c->msg->len-1; -} - -/* is_msgend - * - * returns TRUE if we reached the end of the current message -*/ - -static inline int is_msgend(struct nuc900_i2c *i2c) -{ -	return i2c->msg_ptr >= i2c->msg->len; -} - -/* i2c_nuc900_irq_nextbyte - * - * process an interrupt and work out what to do - */ - -static void i2c_nuc900_irq_nextbyte(struct nuc900_i2c *i2c, -							unsigned long iicstat) -{ -	unsigned char byte; - -	switch (i2c->state) { - -	case STATE_IDLE: -		dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__); -		break; - -	case STATE_STOP: -		dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__); -		nuc900_i2c_disable_irq(i2c); -		break; - -	case STATE_START: -		/* last thing we did was send a start condition on the -		 * bus, or started a new i2c message -		 */ - -		if (iicstat & SLAVE_ACK && -		    !(i2c->msg->flags & I2C_M_IGNORE_NAK)) { -			/* ack was not received... */ - -			dev_dbg(i2c->dev, "ack was not received\n"); -			nuc900_i2c_stop(i2c, -ENXIO); -			break; -		} - -		if (i2c->msg->flags & I2C_M_RD) -			i2c->state = STATE_READ; -		else -			i2c->state = STATE_WRITE; - -		/* terminate the transfer if there is nothing to do -		 * as this is used by the i2c probe to find devices. -		*/ - -		if (is_lastmsg(i2c) && i2c->msg->len == 0) { -			nuc900_i2c_stop(i2c, 0); -			break; -		} - -		if (i2c->state == STATE_READ) -			goto prepare_read; - -		/* fall through to the write state, as we will need to -		 * send a byte as well -		*/ - -	case STATE_WRITE: -		/* we are writing data to the device... check for the -		 * end of the message, and if so, work out what to do -		 */ - -		if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) { -			if (iicstat & SLAVE_ACK) { -				dev_dbg(i2c->dev, "WRITE: No Ack\n"); - -				nuc900_i2c_stop(i2c, -ECONNREFUSED); -				break; -			} -		} - -retry_write: - -		if (!is_msgend(i2c)) { -			byte = i2c->msg->buf[i2c->msg_ptr++]; -			writeb(byte, i2c->regs + TXR); -			writel(I2C_CMD_WRITE, i2c->regs + CMDR); - -		} else if (!is_lastmsg(i2c)) { -			/* we need to go to the next i2c message */ - -			dev_dbg(i2c->dev, "WRITE: Next Message\n"); - -			i2c->msg_ptr = 0; -			i2c->msg_idx++; -			i2c->msg++; - -			/* check to see if we need to do another message */ -			if (i2c->msg->flags & I2C_M_NOSTART) { - -				if (i2c->msg->flags & I2C_M_RD) { -					/* cannot do this, the controller -					 * forces us to send a new START -					 * when we change direction -					*/ - -					nuc900_i2c_stop(i2c, -EINVAL); -				} - -				goto retry_write; -			} else { -				/* send the new start */ -				nuc900_i2c_message_start(i2c, i2c->msg); -				i2c->state = STATE_START; -			} - -		} else { -			/* send stop */ - -			nuc900_i2c_stop(i2c, 0); -		} -		break; - -	case STATE_READ: -		/* we have a byte of data in the data register, do -		 * something with it, and then work out whether we are -		 * going to do any more read/write -		 */ - -		byte = readb(i2c->regs + RXR); -		i2c->msg->buf[i2c->msg_ptr++] = byte; - -prepare_read: -		if (is_msglast(i2c)) { -			/* last byte of buffer */ - -			if (is_lastmsg(i2c)) -				writel(I2C_CMD_READ | I2C_CMD_NACK, -							i2c->regs + CMDR); - -		} else if (is_msgend(i2c)) { -			/* ok, we've read the entire buffer, see if there -			 * is anything else we need to do -			*/ - -			if (is_lastmsg(i2c)) { -				/* last message, send stop and complete */ -				dev_dbg(i2c->dev, "READ: Send Stop\n"); - -				nuc900_i2c_stop(i2c, 0); -			} else { -				/* go to the next transfer */ -				dev_dbg(i2c->dev, "READ: Next Transfer\n"); - -				i2c->msg_ptr = 0; -				i2c->msg_idx++; -				i2c->msg++; - -				writel(I2C_CMD_READ, i2c->regs + CMDR); -			} - -		} else { -			writel(I2C_CMD_READ, i2c->regs + CMDR); -		} - -		break; -	} -} - -/* nuc900_i2c_irq - * - * top level IRQ servicing routine -*/ - -static irqreturn_t nuc900_i2c_irq(int irqno, void *dev_id) -{ -	struct nuc900_i2c *i2c = dev_id; -	unsigned long status; - -	status = readl(i2c->regs + CSR); -	writel(status | IRQFLAG, i2c->regs + CSR); - -	if (status & ARBIT_LOST) { -		/* deal with arbitration loss */ -		dev_err(i2c->dev, "deal with arbitration loss\n"); -		goto out; -	} - -	if (i2c->state == STATE_IDLE) { -		dev_dbg(i2c->dev, "IRQ: error i2c->state == IDLE\n"); -		goto out; -	} - -	/* pretty much this leaves us with the fact that we've -	 * transmitted or received whatever byte we last sent -	*/ - -	i2c_nuc900_irq_nextbyte(i2c, status); - - out: -	return IRQ_HANDLED; -} - - -/* nuc900_i2c_set_master - * - * get the i2c bus for a master transaction -*/ - -static int nuc900_i2c_set_master(struct nuc900_i2c *i2c) -{ -	int timeout = 400; - -	while (timeout-- > 0) { -		if (((readl(i2c->regs + SWR) & I2CSTART) == I2CSTART) && -				((readl(i2c->regs + CSR) & I2CBUSY) == 0)) { -			return 0; -		} - -		msleep(1); -	} - -	return -ETIMEDOUT; -} - -/* nuc900_i2c_doxfer - * - * this starts an i2c transfer -*/ - -static int nuc900_i2c_doxfer(struct nuc900_i2c *i2c, -			      struct i2c_msg *msgs, int num) -{ -	unsigned long iicstat, timeout; -	int spins = 20; -	int ret; - -	ret = nuc900_i2c_set_master(i2c); -	if (ret != 0) { -		dev_err(i2c->dev, "cannot get bus (error %d)\n", ret); -		ret = -EAGAIN; -		goto out; -	} - -	spin_lock_irq(&i2c->lock); - -	i2c->msg     = msgs; -	i2c->msg_num = num; -	i2c->msg_ptr = 0; -	i2c->msg_idx = 0; -	i2c->state   = STATE_START; - -	nuc900_i2c_message_start(i2c, msgs); -	spin_unlock_irq(&i2c->lock); - -	timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5); - -	ret = i2c->msg_idx; - -	/* having these next two as dev_err() makes life very -	 * noisy when doing an i2cdetect -	*/ - -	if (timeout == 0) -		dev_dbg(i2c->dev, "timeout\n"); -	else if (ret != num) -		dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret); - -	/* ensure the stop has been through the bus */ - -	dev_dbg(i2c->dev, "waiting for bus idle\n"); - -	/* first, try busy waiting briefly */ -	do { -		iicstat = readl(i2c->regs + CSR); -	} while ((iicstat & I2CBUSY) && --spins); - -	/* if that timed out sleep */ -	if (!spins) { -		msleep(1); -		iicstat = readl(i2c->regs + CSR); -	} - -	if (iicstat & I2CBUSY) -		dev_warn(i2c->dev, "timeout waiting for bus idle\n"); - - out: -	return ret; -} - -/* nuc900_i2c_xfer - * - * first port of call from the i2c bus code when an message needs - * transferring across the i2c bus. -*/ - -static int nuc900_i2c_xfer(struct i2c_adapter *adap, -			struct i2c_msg *msgs, int num) -{ -	struct nuc900_i2c *i2c = (struct nuc900_i2c *)adap->algo_data; -	int retry; -	int ret; - -	nuc900_i2c_enable_irq(i2c); - -	for (retry = 0; retry < adap->retries; retry++) { - -		ret = nuc900_i2c_doxfer(i2c, msgs, num); - -		if (ret != -EAGAIN) -			return ret; - -		dev_dbg(i2c->dev, "Retrying transmission (%d)\n", retry); - -		udelay(100); -	} - -	return -EREMOTEIO; -} - -/* declare our i2c functionality */ -static u32 nuc900_i2c_func(struct i2c_adapter *adap) -{ -	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART | -		I2C_FUNC_PROTOCOL_MANGLING; -} - -/* i2c bus registration info */ - -static const struct i2c_algorithm nuc900_i2c_algorithm = { -	.master_xfer		= nuc900_i2c_xfer, -	.functionality		= nuc900_i2c_func, -}; - -/* nuc900_i2c_probe - * - * called by the bus driver when a suitable device is found -*/ - -static int nuc900_i2c_probe(struct platform_device *pdev) -{ -	struct nuc900_i2c *i2c; -	struct nuc900_platform_i2c *pdata; -	struct resource *res; -	int ret; - -	pdata = dev_get_platdata(&pdev->dev); -	if (!pdata) { -		dev_err(&pdev->dev, "no platform data\n"); -		return -EINVAL; -	} - -	i2c = kzalloc(sizeof(struct nuc900_i2c), GFP_KERNEL); -	if (!i2c) { -		dev_err(&pdev->dev, "no memory for state\n"); -		return -ENOMEM; -	} - -	strlcpy(i2c->adap.name, "nuc900-i2c0", sizeof(i2c->adap.name)); -	i2c->adap.owner   = THIS_MODULE; -	i2c->adap.algo    = &nuc900_i2c_algorithm; -	i2c->adap.retries = 2; -	i2c->adap.class   = I2C_CLASS_HWMON | I2C_CLASS_SPD; - -	spin_lock_init(&i2c->lock); -	init_waitqueue_head(&i2c->wait); - -	/* find the clock and enable it */ - -	i2c->dev = &pdev->dev; -	i2c->clk = clk_get(&pdev->dev, NULL); -	if (IS_ERR(i2c->clk)) { -		dev_err(&pdev->dev, "cannot get clock\n"); -		ret = -ENOENT; -		goto err_noclk; -	} - -	dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk); - -	clk_enable(i2c->clk); - -	/* map the registers */ - -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (res == NULL) { -		dev_err(&pdev->dev, "cannot find IO resource\n"); -		ret = -ENOENT; -		goto err_clk; -	} - -	i2c->ioarea = request_mem_region(res->start, resource_size(res), -					 pdev->name); - -	if (i2c->ioarea == NULL) { -		dev_err(&pdev->dev, "cannot request IO\n"); -		ret = -ENXIO; -		goto err_clk; -	} - -	i2c->regs = ioremap(res->start, resource_size(res)); - -	if (i2c->regs == NULL) { -		dev_err(&pdev->dev, "cannot map IO\n"); -		ret = -ENXIO; -		goto err_ioarea; -	} - -	dev_dbg(&pdev->dev, "registers %p (%p, %p)\n", -		i2c->regs, i2c->ioarea, res); - -	/* setup info block for the i2c core */ - -	i2c->adap.algo_data = i2c; -	i2c->adap.dev.parent = &pdev->dev; - -	mfp_set_groupg(&pdev->dev, NULL); - -	clk_get_rate(i2c->clk); - -	ret = (i2c->clk.apbfreq)/(pdata->bus_freq * 5) - 1; -	writel(ret & 0xffff, i2c->regs + DIVIDER); - -	/* find the IRQ for this unit (note, this relies on the init call to -	 * ensure no current IRQs pending -	 */ - -	i2c->irq = ret = platform_get_irq(pdev, 0); -	if (ret <= 0) { -		dev_err(&pdev->dev, "cannot find IRQ\n"); -		goto err_iomap; -	} - -	ret = request_irq(i2c->irq, nuc900_i2c_irq, IRQF_SHARED, -			  dev_name(&pdev->dev), i2c); - -	if (ret != 0) { -		dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq); -		goto err_iomap; -	} - -	/* Note, previous versions of the driver used i2c_add_adapter() -	 * to add the bus at any number. We now pass the bus number via -	 * the platform data, so if unset it will now default to always -	 * being bus 0. -	 */ - -	i2c->adap.nr = pdata->bus_num; - -	ret = i2c_add_numbered_adapter(&i2c->adap); -	if (ret < 0) { -		dev_err(&pdev->dev, "failed to add bus to i2c core\n"); -		goto err_irq; -	} - -	platform_set_drvdata(pdev, i2c); - -	dev_info(&pdev->dev, "%s: NUC900 I2C adapter\n", -						dev_name(&i2c->adap.dev)); -	return 0; - - err_irq: -	free_irq(i2c->irq, i2c); - - err_iomap: -	iounmap(i2c->regs); - - err_ioarea: -	release_resource(i2c->ioarea); -	kfree(i2c->ioarea); - - err_clk: -	clk_disable(i2c->clk); -	clk_put(i2c->clk); - - err_noclk: -	kfree(i2c); -	return ret; -} - -/* nuc900_i2c_remove - * - * called when device is removed from the bus -*/ - -static int nuc900_i2c_remove(struct platform_device *pdev) -{ -	struct nuc900_i2c *i2c = platform_get_drvdata(pdev); - -	i2c_del_adapter(&i2c->adap); -	free_irq(i2c->irq, i2c); - -	clk_disable(i2c->clk); -	clk_put(i2c->clk); - -	iounmap(i2c->regs); - -	release_resource(i2c->ioarea); -	kfree(i2c->ioarea); -	kfree(i2c); - -	return 0; -} - -static struct platform_driver nuc900_i2c_driver = { -	.probe		= nuc900_i2c_probe, -	.remove		= nuc900_i2c_remove, -	.driver		= { -		.owner	= THIS_MODULE, -		.name	= "nuc900-i2c0", -	}, -}; - -static int __init i2c_adap_nuc900_init(void) -{ -	return platform_driver_register(&nuc900_i2c_driver); -} - -static void __exit i2c_adap_nuc900_exit(void) -{ -	platform_driver_unregister(&nuc900_i2c_driver); -} -subsys_initcall(i2c_adap_nuc900_init); -module_exit(i2c_adap_nuc900_exit); - -MODULE_DESCRIPTION("NUC900 I2C Bus driver"); -MODULE_AUTHOR("Wan ZongShun, <mcuos.com-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:nuc900-i2c0"); diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index c61f37a10a0..0e10cc6182f 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -15,7 +15,6 @@  #include <linux/err.h>  #include <linux/kernel.h>  #include <linux/module.h> -#include <linux/init.h>  #include <linux/errno.h>  #include <linux/platform_device.h>  #include <linux/i2c.h> @@ -247,11 +246,11 @@ static const struct i2c_algorithm ocores_algorithm = {  static struct i2c_adapter ocores_adapter = {  	.owner		= THIS_MODULE,  	.name		= "i2c-ocores", -	.class		= I2C_CLASS_HWMON | I2C_CLASS_SPD, +	.class		= I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED,  	.algo		= &ocores_algorithm,  }; -static struct of_device_id ocores_i2c_match[] = { +static const struct of_device_id ocores_i2c_match[] = {  	{  		.compatible = "opencores,i2c-ocores",  		.data = (void *)TYPE_OCORES, diff --git a/drivers/i2c/busses/i2c-octeon.c b/drivers/i2c/busses/i2c-octeon.c index b929ba271b4..81042b08a94 100644 --- a/drivers/i2c/busses/i2c-octeon.c +++ b/drivers/i2c/busses/i2c-octeon.c @@ -18,7 +18,6 @@  #include <linux/delay.h>  #include <linux/sched.h>  #include <linux/slab.h> -#include <linux/init.h>  #include <linux/i2c.h>  #include <linux/io.h>  #include <linux/of.h> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 6d8308d5dc4..b182793a405 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -266,13 +266,13 @@ static const u8 reg_map_ip_v2[] = {  static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,  				      int reg, u16 val)  { -	__raw_writew(val, i2c_dev->base + +	writew_relaxed(val, i2c_dev->base +  			(i2c_dev->regs[reg] << i2c_dev->reg_shift));  }  static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)  { -	return __raw_readw(i2c_dev->base + +	return readw_relaxed(i2c_dev->base +  				(i2c_dev->regs[reg] << i2c_dev->reg_shift));  } @@ -543,7 +543,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,  	w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR;  	omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, w); -	INIT_COMPLETION(dev->cmd_complete); +	reinit_completion(&dev->cmd_complete);  	dev->cmd_err = 0;  	w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT; @@ -636,7 +636,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)  	int r;  	r = pm_runtime_get_sync(dev->dev); -	if (IS_ERR_VALUE(r)) +	if (r < 0)  		goto out;  	r = omap_i2c_wait_for_bb(dev); @@ -939,6 +939,9 @@ omap_i2c_isr_thread(int this_irq, void *dev_id)  		/*  		 * ProDB0017052: Clear ARDY bit twice  		 */ +		if (stat & OMAP_I2C_STAT_ARDY) +			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ARDY); +  		if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |  					OMAP_I2C_STAT_AL)) {  			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY | @@ -1034,6 +1037,20 @@ static const struct i2c_algorithm omap_i2c_algo = {  };  #ifdef CONFIG_OF +static struct omap_i2c_bus_platform_data omap2420_pdata = { +	.rev = OMAP_I2C_IP_VERSION_1, +	.flags = OMAP_I2C_FLAG_NO_FIFO | +			OMAP_I2C_FLAG_SIMPLE_CLOCK | +			OMAP_I2C_FLAG_16BIT_DATA_REG | +			OMAP_I2C_FLAG_BUS_SHIFT_2, +}; + +static struct omap_i2c_bus_platform_data omap2430_pdata = { +	.rev = OMAP_I2C_IP_VERSION_1, +	.flags = OMAP_I2C_FLAG_BUS_SHIFT_2 | +			OMAP_I2C_FLAG_FORCE_19200_INT_CLK, +}; +  static struct omap_i2c_bus_platform_data omap3_pdata = {  	.rev = OMAP_I2C_IP_VERSION_1,  	.flags = OMAP_I2C_FLAG_BUS_SHIFT_2, @@ -1052,6 +1069,14 @@ static const struct of_device_id omap_i2c_of_match[] = {  		.compatible = "ti,omap3-i2c",  		.data = &omap3_pdata,  	}, +	{ +		.compatible = "ti,omap2430-i2c", +		.data = &omap2430_pdata, +	}, +	{ +		.compatible = "ti,omap2420-i2c", +		.data = &omap2420_pdata, +	},  	{ },  };  MODULE_DEVICE_TABLE(of, omap_i2c_of_match); @@ -1089,10 +1114,8 @@ omap_i2c_probe(struct platform_device *pdev)  	}  	dev = devm_kzalloc(&pdev->dev, sizeof(struct omap_i2c_dev), GFP_KERNEL); -	if (!dev) { -		dev_err(&pdev->dev, "Menory allocation failed\n"); +	if (!dev)  		return -ENOMEM; -	}  	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	dev->base = devm_ioremap_resource(&pdev->dev, mem); @@ -1130,16 +1153,16 @@ omap_i2c_probe(struct platform_device *pdev)  	pm_runtime_use_autosuspend(dev->dev);  	r = pm_runtime_get_sync(dev->dev); -	if (IS_ERR_VALUE(r)) +	if (r < 0)  		goto err_free_mem;  	/*  	 * Read the Rev hi bit-[15:14] ie scheme this is 1 indicates ver2.  	 * On omap1/3/2 Offset 4 is IE Reg the bit [15:14] is 0 at reset.  	 * Also since the omap_i2c_read_reg uses reg_map_ip_* a -	 * raw_readw is done. +	 * readw_relaxed is done.  	 */ -	rev = __raw_readw(dev->base + 0x04); +	rev = readw_relaxed(dev->base + 0x04);  	dev->scheme = OMAP_I2C_SCHEME(rev);  	switch (dev->scheme) { @@ -1213,7 +1236,7 @@ omap_i2c_probe(struct platform_device *pdev)  	adap = &dev->adapter;  	i2c_set_adapdata(adap, dev);  	adap->owner = THIS_MODULE; -	adap->class = I2C_CLASS_HWMON; +	adap->class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED;  	strlcpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));  	adap->algo = &omap_i2c_algo;  	adap->dev.parent = &pdev->dev; @@ -1251,7 +1274,7 @@ static int omap_i2c_remove(struct platform_device *pdev)  	i2c_del_adapter(&dev->adapter);  	ret = pm_runtime_get_sync(&pdev->dev); -	if (IS_ERR_VALUE(ret)) +	if (ret < 0)  		return ret;  	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c index aa957788192..62f55fe624c 100644 --- a/drivers/i2c/busses/i2c-parport-light.c +++ b/drivers/i2c/busses/i2c-parport-light.c @@ -1,7 +1,7 @@  /* ------------------------------------------------------------------------ *   * i2c-parport-light.c I2C bus over parallel port                           *   * ------------------------------------------------------------------------ * -   Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org> +   Copyright (C) 2003-2010 Jean Delvare <jdelvare@suse.de>     Based on older i2c-velleman.c driver     Copyright (C) 1995-2000 Simon G. Vogl @@ -273,7 +273,7 @@ static void __exit i2c_parport_exit(void)  	release_region(base, 3);  } -MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); +MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");  MODULE_DESCRIPTION("I2C bus over parallel port (light)");  MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 81d88786962..a27aae2d675 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c @@ -1,7 +1,7 @@  /* ------------------------------------------------------------------------ *   * i2c-parport.c I2C bus over parallel port                                 *   * ------------------------------------------------------------------------ * -   Copyright (C) 2003-2011 Jean Delvare <khali@linux-fr.org> +   Copyright (C) 2003-2011 Jean Delvare <jdelvare@suse.de>     Based on older i2c-philips-par.c driver     Copyright (C) 1995-2000 Simon G. Vogl @@ -298,7 +298,7 @@ static void __exit i2c_parport_exit(void)  	parport_unregister_driver(&i2c_parport_driver);  } -MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); +MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");  MODULE_DESCRIPTION("I2C bus over parallel port");  MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-parport.h b/drivers/i2c/busses/i2c-parport.h index 3fe652302ea..e572f3aac0f 100644 --- a/drivers/i2c/busses/i2c-parport.h +++ b/drivers/i2c/busses/i2c-parport.h @@ -1,7 +1,7 @@  /* ------------------------------------------------------------------------ *   * i2c-parport.h I2C bus over parallel port                                 *   * ------------------------------------------------------------------------ * -   Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org> +   Copyright (C) 2003-2010 Jean Delvare <jdelvare@suse.de>     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 diff --git a/drivers/i2c/busses/i2c-pasemi.c b/drivers/i2c/busses/i2c-pasemi.c index 615f632c846..7a9dce43e11 100644 --- a/drivers/i2c/busses/i2c-pasemi.c +++ b/drivers/i2c/busses/i2c-pasemi.c @@ -401,7 +401,7 @@ static void pasemi_smb_remove(struct pci_dev *dev)  	kfree(smbus);  } -static DEFINE_PCI_DEVICE_TABLE(pasemi_smb_ids) = { +static const struct pci_device_id pasemi_smb_ids[] = {  	{ PCI_DEVICE(0x1959, 0xa003) },  	{ 0, }  }; diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index 39e2755e3f2..845f12598e7 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c @@ -12,7 +12,6 @@   */  #include <linux/kernel.h>  #include <linux/module.h> -#include <linux/init.h>  #include <linux/slab.h>  #include <linux/delay.h>  #include <linux/jiffies.h> diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index a028617b8f1..a6f54ba27e2 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -22,7 +22,7 @@  	Intel PIIX4, 440MX  	Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100  	ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800 -	AMD Hudson-2, CZ +	AMD Hudson-2, ML, CZ  	SMSC Victory66     Note: we assume there can only be one device, with one or more @@ -38,7 +38,6 @@  #include <linux/ioport.h>  #include <linux/i2c.h>  #include <linux/slab.h> -#include <linux/init.h>  #include <linux/dmi.h>  #include <linux/acpi.h>  #include <linux/io.h> @@ -208,16 +207,16 @@ static int piix4_setup(struct pci_dev *PIIX4_dev,  				   "WARNING: SMBus interface has been FORCEFULLY ENABLED!\n");  		} else {  			dev_err(&PIIX4_dev->dev, -				"Host SMBus controller not enabled!\n"); +				"SMBus Host Controller not enabled!\n");  			release_region(piix4_smba, SMBIOSIZE);  			return -ENODEV;  		}  	}  	if (((temp & 0x0E) == 8) || ((temp & 0x0E) == 2)) -		dev_dbg(&PIIX4_dev->dev, "Using Interrupt 9 for SMBus.\n"); +		dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus\n");  	else if ((temp & 0x0E) == 0) -		dev_dbg(&PIIX4_dev->dev, "Using Interrupt SMI# for SMBus.\n"); +		dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus\n");  	else  		dev_err(&PIIX4_dev->dev, "Illegal Interrupt configuration "  			"(or code out of date)!\n"); @@ -235,7 +234,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,  {  	unsigned short piix4_smba;  	unsigned short smba_idx = 0xcd6; -	u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en; +	u8 smba_en_lo, smba_en_hi, smb_en, smb_en_status; +	u8 i2ccfg, i2ccfg_offset = 0x10;  	/* SB800 and later SMBus does not support forcing address */  	if (force || force_addr) { @@ -245,7 +245,15 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,  	}  	/* Determine the address of the SMBus areas */ -	smb_en = (aux) ? 0x28 : 0x2c; +	if ((PIIX4_dev->vendor == PCI_VENDOR_ID_AMD && +	     PIIX4_dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS && +	     PIIX4_dev->revision >= 0x41) || +	    (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD && +	     PIIX4_dev->device == 0x790b && +	     PIIX4_dev->revision >= 0x49)) +		smb_en = 0x00; +	else +		smb_en = (aux) ? 0x28 : 0x2c;  	if (!request_region(smba_idx, 2, "smba_idx")) {  		dev_err(&PIIX4_dev->dev, "SMBus base address index region " @@ -258,13 +266,22 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,  	smba_en_hi = inb_p(smba_idx + 1);  	release_region(smba_idx, 2); -	if ((smba_en_lo & 1) == 0) { +	if (!smb_en) { +		smb_en_status = smba_en_lo & 0x10; +		piix4_smba = smba_en_hi << 8; +		if (aux) +			piix4_smba |= 0x20; +	} else { +		smb_en_status = smba_en_lo & 0x01; +		piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; +	} + +	if (!smb_en_status) {  		dev_err(&PIIX4_dev->dev, -			"Host SMBus controller not enabled!\n"); +			"SMBus Host Controller not enabled!\n");  		return -ENODEV;  	} -	piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;  	if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))  		return -ENODEV; @@ -277,7 +294,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,  	/* Aux SMBus does not support IRQ information */  	if (aux) {  		dev_info(&PIIX4_dev->dev, -			 "SMBus Host Controller at 0x%x\n", piix4_smba); +			 "Auxiliary SMBus Host Controller at 0x%x\n", +			 piix4_smba);  		return piix4_smba;  	} @@ -292,9 +310,9 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,  	release_region(piix4_smba + i2ccfg_offset, 1);  	if (i2ccfg & 1) -		dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus.\n"); +		dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus\n");  	else -		dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus.\n"); +		dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus\n");  	dev_info(&PIIX4_dev->dev,  		 "SMBus Host Controller at 0x%x, revision %d\n", @@ -522,7 +540,7 @@ static const struct i2c_algorithm smbus_algorithm = {  	.functionality	= piix4_func,  }; -static DEFINE_PCI_DEVICE_TABLE(piix4_ids) = { +static const struct pci_device_id piix4_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) },  	{ PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3) }, diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c index f6389e2c9d0..8564768fee3 100644 --- a/drivers/i2c/busses/i2c-pmcmsp.c +++ b/drivers/i2c/busses/i2c-pmcmsp.c @@ -26,7 +26,6 @@  #include <linux/kernel.h>  #include <linux/module.h> -#include <linux/init.h>  #include <linux/platform_device.h>  #include <linux/i2c.h>  #include <linux/interrupt.h> diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 1a9ea25f231..dc7ff829ad7 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -23,6 +23,7 @@  #include <linux/err.h>  #include <linux/clk.h>  #include <linux/slab.h> +#include <linux/of.h>  #define I2C_PNX_TIMEOUT_DEFAULT		10 /* msec */  #define I2C_PNX_SPEED_KHZ_DEFAULT	100 @@ -627,11 +628,9 @@ static int i2c_pnx_probe(struct platform_device *pdev)  	struct resource *res;  	u32 speed = I2C_PNX_SPEED_KHZ_DEFAULT * 1000; -	alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL); -	if (!alg_data) { -		ret = -ENOMEM; -		goto err_kzalloc; -	} +	alg_data = devm_kzalloc(&pdev->dev, sizeof(*alg_data), GFP_KERNEL); +	if (!alg_data) +		return -ENOMEM;  	platform_set_drvdata(pdev, alg_data); @@ -656,11 +655,9 @@ static int i2c_pnx_probe(struct platform_device *pdev)  		 */  	}  #endif -	alg_data->clk = clk_get(&pdev->dev, NULL); -	if (IS_ERR(alg_data->clk)) { -		ret = PTR_ERR(alg_data->clk); -		goto out_drvdata; -	} +	alg_data->clk = devm_clk_get(&pdev->dev, NULL); +	if (IS_ERR(alg_data->clk)) +		return PTR_ERR(alg_data->clk);  	init_timer(&alg_data->mif.timer);  	alg_data->mif.timer.function = i2c_pnx_timeout; @@ -671,31 +668,13 @@ static int i2c_pnx_probe(struct platform_device *pdev)  	/* Register I/O resource */  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		dev_err(&pdev->dev, "Unable to get mem resource.\n"); -		ret = -EBUSY; -		goto out_clkget; -	} -	if (!request_mem_region(res->start, I2C_PNX_REGION_SIZE, -				pdev->name)) { -		dev_err(&pdev->dev, -		       "I/O region 0x%08x for I2C already in use.\n", -		       res->start); -		ret = -ENOMEM; -		goto out_clkget; -	} - -	alg_data->base = res->start; -	alg_data->ioaddr = ioremap(res->start, I2C_PNX_REGION_SIZE); -	if (!alg_data->ioaddr) { -		dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n"); -		ret = -ENOMEM; -		goto out_release; -	} +	alg_data->ioaddr = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(alg_data->ioaddr)) +		return PTR_ERR(alg_data->ioaddr);  	ret = clk_enable(alg_data->clk);  	if (ret) -		goto out_unmap; +		return ret;  	freq = clk_get_rate(alg_data->clk); @@ -729,8 +708,8 @@ static int i2c_pnx_probe(struct platform_device *pdev)  		ret = alg_data->irq;  		goto out_clock;  	} -	ret = request_irq(alg_data->irq, i2c_pnx_interrupt, -			0, pdev->name, alg_data); +	ret = devm_request_irq(&pdev->dev, alg_data->irq, i2c_pnx_interrupt, +			       0, pdev->name, alg_data);  	if (ret)  		goto out_clock; @@ -738,7 +717,7 @@ static int i2c_pnx_probe(struct platform_device *pdev)  	ret = i2c_add_numbered_adapter(&alg_data->adapter);  	if (ret < 0) {  		dev_err(&pdev->dev, "I2C: Failed to add bus\n"); -		goto out_irq; +		goto out_clock;  	}  	dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n", @@ -746,19 +725,8 @@ static int i2c_pnx_probe(struct platform_device *pdev)  	return 0; -out_irq: -	free_irq(alg_data->irq, alg_data);  out_clock:  	clk_disable(alg_data->clk); -out_unmap: -	iounmap(alg_data->ioaddr); -out_release: -	release_mem_region(res->start, I2C_PNX_REGION_SIZE); -out_clkget: -	clk_put(alg_data->clk); -out_drvdata: -	kfree(alg_data); -err_kzalloc:  	return ret;  } @@ -766,13 +734,8 @@ static int i2c_pnx_remove(struct platform_device *pdev)  {  	struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); -	free_irq(alg_data->irq, alg_data);  	i2c_del_adapter(&alg_data->adapter);  	clk_disable(alg_data->clk); -	iounmap(alg_data->ioaddr); -	release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); -	clk_put(alg_data->clk); -	kfree(alg_data);  	return 0;  } diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index 37e8cfad625..01e967763c2 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c @@ -24,9 +24,9 @@  #include <linux/kernel.h>  #include <linux/types.h>  #include <linux/i2c.h> -#include <linux/init.h>  #include <linux/device.h>  #include <linux/platform_device.h> +#include <linux/of_irq.h>  #include <asm/prom.h>  #include <asm/pmac_low_i2c.h> diff --git a/drivers/i2c/busses/i2c-puv3.c b/drivers/i2c/busses/i2c-puv3.c index ac80199885b..c83fc3ccdd2 100644 --- a/drivers/i2c/busses/i2c-puv3.c +++ b/drivers/i2c/busses/i2c-puv3.c @@ -17,7 +17,6 @@  #include <linux/types.h>  #include <linux/delay.h>  #include <linux/i2c.h> -#include <linux/init.h>  #include <linux/clk.h>  #include <linux/platform_device.h>  #include <linux/io.h> diff --git a/drivers/i2c/busses/i2c-pxa-pci.c b/drivers/i2c/busses/i2c-pxa-pci.c index 9639be86e53..417464e9ea2 100644 --- a/drivers/i2c/busses/i2c-pxa-pci.c +++ b/drivers/i2c/busses/i2c-pxa-pci.c @@ -148,7 +148,7 @@ static void ce4100_i2c_remove(struct pci_dev *dev)  	kfree(sds);  } -static DEFINE_PCI_DEVICE_TABLE(ce4100_i2c_devices) = { +static const struct pci_device_id ce4100_i2c_devices[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e68)},  	{ },  }; diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index bbe6dfbc5c0..be671f7a0e0 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -1084,7 +1084,7 @@ static const struct i2c_algorithm i2c_pxa_pio_algorithm = {  	.functionality	= i2c_pxa_functionality,  }; -static struct of_device_id i2c_pxa_dt_ids[] = { +static const struct of_device_id i2c_pxa_dt_ids[] = {  	{ .compatible = "mrvl,pxa-i2c", .data = (void *)REGS_PXA2XX },  	{ .compatible = "mrvl,pwri2c", .data = (void *)REGS_PXA3XX },  	{ .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA2XX }, diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c new file mode 100644 index 00000000000..2a5efb5b487 --- /dev/null +++ b/drivers/i2c/busses/i2c-qup.c @@ -0,0 +1,768 @@ +/* + * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved. + * Copyright (c) 2014, Sony Mobile Communications AB. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> + +/* QUP Registers */ +#define QUP_CONFIG		0x000 +#define QUP_STATE		0x004 +#define QUP_IO_MODE		0x008 +#define QUP_SW_RESET		0x00c +#define QUP_OPERATIONAL		0x018 +#define QUP_ERROR_FLAGS		0x01c +#define QUP_ERROR_FLAGS_EN	0x020 +#define QUP_HW_VERSION		0x030 +#define QUP_MX_OUTPUT_CNT	0x100 +#define QUP_OUT_FIFO_BASE	0x110 +#define QUP_MX_WRITE_CNT	0x150 +#define QUP_MX_INPUT_CNT	0x200 +#define QUP_MX_READ_CNT		0x208 +#define QUP_IN_FIFO_BASE	0x218 +#define QUP_I2C_CLK_CTL		0x400 +#define QUP_I2C_STATUS		0x404 + +/* QUP States and reset values */ +#define QUP_RESET_STATE		0 +#define QUP_RUN_STATE		1 +#define QUP_PAUSE_STATE		3 +#define QUP_STATE_MASK		3 + +#define QUP_STATE_VALID		BIT(2) +#define QUP_I2C_MAST_GEN	BIT(4) + +#define QUP_OPERATIONAL_RESET	0x000ff0 +#define QUP_I2C_STATUS_RESET	0xfffffc + +/* QUP OPERATIONAL FLAGS */ +#define QUP_I2C_NACK_FLAG	BIT(3) +#define QUP_OUT_NOT_EMPTY	BIT(4) +#define QUP_IN_NOT_EMPTY	BIT(5) +#define QUP_OUT_FULL		BIT(6) +#define QUP_OUT_SVC_FLAG	BIT(8) +#define QUP_IN_SVC_FLAG		BIT(9) +#define QUP_MX_OUTPUT_DONE	BIT(10) +#define QUP_MX_INPUT_DONE	BIT(11) + +/* I2C mini core related values */ +#define QUP_CLOCK_AUTO_GATE	BIT(13) +#define I2C_MINI_CORE		(2 << 8) +#define I2C_N_VAL		15 +/* Most significant word offset in FIFO port */ +#define QUP_MSW_SHIFT		(I2C_N_VAL + 1) + +/* Packing/Unpacking words in FIFOs, and IO modes */ +#define QUP_OUTPUT_BLK_MODE	(1 << 10) +#define QUP_INPUT_BLK_MODE	(1 << 12) +#define QUP_UNPACK_EN		BIT(14) +#define QUP_PACK_EN		BIT(15) + +#define QUP_REPACK_EN		(QUP_UNPACK_EN | QUP_PACK_EN) + +#define QUP_OUTPUT_BLOCK_SIZE(x)(((x) >> 0) & 0x03) +#define QUP_OUTPUT_FIFO_SIZE(x)	(((x) >> 2) & 0x07) +#define QUP_INPUT_BLOCK_SIZE(x)	(((x) >> 5) & 0x03) +#define QUP_INPUT_FIFO_SIZE(x)	(((x) >> 7) & 0x07) + +/* QUP tags */ +#define QUP_TAG_START		(1 << 8) +#define QUP_TAG_DATA		(2 << 8) +#define QUP_TAG_STOP		(3 << 8) +#define QUP_TAG_REC		(4 << 8) + +/* Status, Error flags */ +#define I2C_STATUS_WR_BUFFER_FULL	BIT(0) +#define I2C_STATUS_BUS_ACTIVE		BIT(8) +#define I2C_STATUS_ERROR_MASK		0x38000fc +#define QUP_STATUS_ERROR_FLAGS		0x7c + +#define QUP_READ_LIMIT			256 + +struct qup_i2c_dev { +	struct device		*dev; +	void __iomem		*base; +	int			irq; +	struct clk		*clk; +	struct clk		*pclk; +	struct i2c_adapter	adap; + +	int			clk_ctl; +	int			out_fifo_sz; +	int			in_fifo_sz; +	int			out_blk_sz; +	int			in_blk_sz; + +	unsigned long		one_byte_t; + +	struct i2c_msg		*msg; +	/* Current posion in user message buffer */ +	int			pos; +	/* I2C protocol errors */ +	u32			bus_err; +	/* QUP core errors */ +	u32			qup_err; + +	struct completion	xfer; +}; + +static irqreturn_t qup_i2c_interrupt(int irq, void *dev) +{ +	struct qup_i2c_dev *qup = dev; +	u32 bus_err; +	u32 qup_err; +	u32 opflags; + +	bus_err = readl(qup->base + QUP_I2C_STATUS); +	qup_err = readl(qup->base + QUP_ERROR_FLAGS); +	opflags = readl(qup->base + QUP_OPERATIONAL); + +	if (!qup->msg) { +		/* Clear Error interrupt */ +		writel(QUP_RESET_STATE, qup->base + QUP_STATE); +		return IRQ_HANDLED; +	} + +	bus_err &= I2C_STATUS_ERROR_MASK; +	qup_err &= QUP_STATUS_ERROR_FLAGS; + +	if (qup_err) { +		/* Clear Error interrupt */ +		writel(qup_err, qup->base + QUP_ERROR_FLAGS); +		goto done; +	} + +	if (bus_err) { +		/* Clear Error interrupt */ +		writel(QUP_RESET_STATE, qup->base + QUP_STATE); +		goto done; +	} + +	if (opflags & QUP_IN_SVC_FLAG) +		writel(QUP_IN_SVC_FLAG, qup->base + QUP_OPERATIONAL); + +	if (opflags & QUP_OUT_SVC_FLAG) +		writel(QUP_OUT_SVC_FLAG, qup->base + QUP_OPERATIONAL); + +done: +	qup->qup_err = qup_err; +	qup->bus_err = bus_err; +	complete(&qup->xfer); +	return IRQ_HANDLED; +} + +static int qup_i2c_poll_state_mask(struct qup_i2c_dev *qup, +				   u32 req_state, u32 req_mask) +{ +	int retries = 1; +	u32 state; + +	/* +	 * State transition takes 3 AHB clocks cycles + 3 I2C master clock +	 * cycles. So retry once after a 1uS delay. +	 */ +	do { +		state = readl(qup->base + QUP_STATE); + +		if (state & QUP_STATE_VALID && +		    (state & req_mask) == req_state) +			return 0; + +		udelay(1); +	} while (retries--); + +	return -ETIMEDOUT; +} + +static int qup_i2c_poll_state(struct qup_i2c_dev *qup, u32 req_state) +{ +	return qup_i2c_poll_state_mask(qup, req_state, QUP_STATE_MASK); +} + +static int qup_i2c_poll_state_valid(struct qup_i2c_dev *qup) +{ +	return qup_i2c_poll_state_mask(qup, 0, 0); +} + +static int qup_i2c_poll_state_i2c_master(struct qup_i2c_dev *qup) +{ +	return qup_i2c_poll_state_mask(qup, QUP_I2C_MAST_GEN, QUP_I2C_MAST_GEN); +} + +static int qup_i2c_change_state(struct qup_i2c_dev *qup, u32 state) +{ +	if (qup_i2c_poll_state_valid(qup) != 0) +		return -EIO; + +	writel(state, qup->base + QUP_STATE); + +	if (qup_i2c_poll_state(qup, state) != 0) +		return -EIO; +	return 0; +} + +static int qup_i2c_wait_writeready(struct qup_i2c_dev *qup) +{ +	unsigned long timeout; +	u32 opflags; +	u32 status; + +	timeout = jiffies + HZ; + +	for (;;) { +		opflags = readl(qup->base + QUP_OPERATIONAL); +		status = readl(qup->base + QUP_I2C_STATUS); + +		if (!(opflags & QUP_OUT_NOT_EMPTY) && +		    !(status & I2C_STATUS_BUS_ACTIVE)) +			return 0; + +		if (time_after(jiffies, timeout)) +			return -ETIMEDOUT; + +		usleep_range(qup->one_byte_t, qup->one_byte_t * 2); +	} +} + +static void qup_i2c_set_write_mode(struct qup_i2c_dev *qup, struct i2c_msg *msg) +{ +	/* Number of entries to shift out, including the start */ +	int total = msg->len + 1; + +	if (total < qup->out_fifo_sz) { +		/* FIFO mode */ +		writel(QUP_REPACK_EN, qup->base + QUP_IO_MODE); +		writel(total, qup->base + QUP_MX_WRITE_CNT); +	} else { +		/* BLOCK mode (transfer data on chunks) */ +		writel(QUP_OUTPUT_BLK_MODE | QUP_REPACK_EN, +		       qup->base + QUP_IO_MODE); +		writel(total, qup->base + QUP_MX_OUTPUT_CNT); +	} +} + +static void qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg) +{ +	u32 addr = msg->addr << 1; +	u32 qup_tag; +	u32 opflags; +	int idx; +	u32 val; + +	if (qup->pos == 0) { +		val = QUP_TAG_START | addr; +		idx = 1; +	} else { +		val = 0; +		idx = 0; +	} + +	while (qup->pos < msg->len) { +		/* Check that there's space in the FIFO for our pair */ +		opflags = readl(qup->base + QUP_OPERATIONAL); +		if (opflags & QUP_OUT_FULL) +			break; + +		if (qup->pos == msg->len - 1) +			qup_tag = QUP_TAG_STOP; +		else +			qup_tag = QUP_TAG_DATA; + +		if (idx & 1) +			val |= (qup_tag | msg->buf[qup->pos]) << QUP_MSW_SHIFT; +		else +			val = qup_tag | msg->buf[qup->pos]; + +		/* Write out the pair and the last odd value */ +		if (idx & 1 || qup->pos == msg->len - 1) +			writel(val, qup->base + QUP_OUT_FIFO_BASE); + +		qup->pos++; +		idx++; +	} +} + +static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg) +{ +	unsigned long left; +	int ret; + +	qup->msg = msg; +	qup->pos = 0; + +	enable_irq(qup->irq); + +	qup_i2c_set_write_mode(qup, msg); + +	ret = qup_i2c_change_state(qup, QUP_RUN_STATE); +	if (ret) +		goto err; + +	writel(qup->clk_ctl, qup->base + QUP_I2C_CLK_CTL); + +	do { +		ret = qup_i2c_change_state(qup, QUP_PAUSE_STATE); +		if (ret) +			goto err; + +		qup_i2c_issue_write(qup, msg); + +		ret = qup_i2c_change_state(qup, QUP_RUN_STATE); +		if (ret) +			goto err; + +		left = wait_for_completion_timeout(&qup->xfer, HZ); +		if (!left) { +			writel(1, qup->base + QUP_SW_RESET); +			ret = -ETIMEDOUT; +			goto err; +		} + +		if (qup->bus_err || qup->qup_err) { +			if (qup->bus_err & QUP_I2C_NACK_FLAG) +				dev_err(qup->dev, "NACK from %x\n", msg->addr); +			ret = -EIO; +			goto err; +		} +	} while (qup->pos < msg->len); + +	/* Wait for the outstanding data in the fifo to drain */ +	ret = qup_i2c_wait_writeready(qup); + +err: +	disable_irq(qup->irq); +	qup->msg = NULL; + +	return ret; +} + +static void qup_i2c_set_read_mode(struct qup_i2c_dev *qup, int len) +{ +	if (len < qup->in_fifo_sz) { +		/* FIFO mode */ +		writel(QUP_REPACK_EN, qup->base + QUP_IO_MODE); +		writel(len, qup->base + QUP_MX_READ_CNT); +	} else { +		/* BLOCK mode (transfer data on chunks) */ +		writel(QUP_INPUT_BLK_MODE | QUP_REPACK_EN, +		       qup->base + QUP_IO_MODE); +		writel(len, qup->base + QUP_MX_INPUT_CNT); +	} +} + +static void qup_i2c_issue_read(struct qup_i2c_dev *qup, struct i2c_msg *msg) +{ +	u32 addr, len, val; + +	addr = (msg->addr << 1) | 1; + +	/* 0 is used to specify a length 256 (QUP_READ_LIMIT) */ +	len = (msg->len == QUP_READ_LIMIT) ? 0 : msg->len; + +	val = ((QUP_TAG_REC | len) << QUP_MSW_SHIFT) | QUP_TAG_START | addr; +	writel(val, qup->base + QUP_OUT_FIFO_BASE); +} + + +static void qup_i2c_read_fifo(struct qup_i2c_dev *qup, struct i2c_msg *msg) +{ +	u32 opflags; +	u32 val = 0; +	int idx; + +	for (idx = 0; qup->pos < msg->len; idx++) { +		if ((idx & 1) == 0) { +			/* Check that FIFO have data */ +			opflags = readl(qup->base + QUP_OPERATIONAL); +			if (!(opflags & QUP_IN_NOT_EMPTY)) +				break; + +			/* Reading 2 words at time */ +			val = readl(qup->base + QUP_IN_FIFO_BASE); + +			msg->buf[qup->pos++] = val & 0xFF; +		} else { +			msg->buf[qup->pos++] = val >> QUP_MSW_SHIFT; +		} +	} +} + +static int qup_i2c_read_one(struct qup_i2c_dev *qup, struct i2c_msg *msg) +{ +	unsigned long left; +	int ret; + +	/* +	 * The QUP block will issue a NACK and STOP on the bus when reaching +	 * the end of the read, the length of the read is specified as one byte +	 * which limits the possible read to 256 (QUP_READ_LIMIT) bytes. +	 */ +	if (msg->len > QUP_READ_LIMIT) { +		dev_err(qup->dev, "HW not capable of reads over %d bytes\n", +			QUP_READ_LIMIT); +		return -EINVAL; +	} + +	qup->msg = msg; +	qup->pos  = 0; + +	enable_irq(qup->irq); + +	qup_i2c_set_read_mode(qup, msg->len); + +	ret = qup_i2c_change_state(qup, QUP_RUN_STATE); +	if (ret) +		goto err; + +	writel(qup->clk_ctl, qup->base + QUP_I2C_CLK_CTL); + +	ret = qup_i2c_change_state(qup, QUP_PAUSE_STATE); +	if (ret) +		goto err; + +	qup_i2c_issue_read(qup, msg); + +	ret = qup_i2c_change_state(qup, QUP_RUN_STATE); +	if (ret) +		goto err; + +	do { +		left = wait_for_completion_timeout(&qup->xfer, HZ); +		if (!left) { +			writel(1, qup->base + QUP_SW_RESET); +			ret = -ETIMEDOUT; +			goto err; +		} + +		if (qup->bus_err || qup->qup_err) { +			if (qup->bus_err & QUP_I2C_NACK_FLAG) +				dev_err(qup->dev, "NACK from %x\n", msg->addr); +			ret = -EIO; +			goto err; +		} + +		qup_i2c_read_fifo(qup, msg); +	} while (qup->pos < msg->len); + +err: +	disable_irq(qup->irq); +	qup->msg = NULL; + +	return ret; +} + +static int qup_i2c_xfer(struct i2c_adapter *adap, +			struct i2c_msg msgs[], +			int num) +{ +	struct qup_i2c_dev *qup = i2c_get_adapdata(adap); +	int ret, idx; + +	ret = pm_runtime_get_sync(qup->dev); +	if (ret < 0) +		goto out; + +	writel(1, qup->base + QUP_SW_RESET); +	ret = qup_i2c_poll_state(qup, QUP_RESET_STATE); +	if (ret) +		goto out; + +	/* Configure QUP as I2C mini core */ +	writel(I2C_MINI_CORE | I2C_N_VAL, qup->base + QUP_CONFIG); + +	for (idx = 0; idx < num; idx++) { +		if (msgs[idx].len == 0) { +			ret = -EINVAL; +			goto out; +		} + +		if (qup_i2c_poll_state_i2c_master(qup)) { +			ret = -EIO; +			goto out; +		} + +		if (msgs[idx].flags & I2C_M_RD) +			ret = qup_i2c_read_one(qup, &msgs[idx]); +		else +			ret = qup_i2c_write_one(qup, &msgs[idx]); + +		if (ret) +			break; + +		ret = qup_i2c_change_state(qup, QUP_RESET_STATE); +		if (ret) +			break; +	} + +	if (ret == 0) +		ret = num; +out: + +	pm_runtime_mark_last_busy(qup->dev); +	pm_runtime_put_autosuspend(qup->dev); + +	return ret; +} + +static u32 qup_i2c_func(struct i2c_adapter *adap) +{ +	return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); +} + +static const struct i2c_algorithm qup_i2c_algo = { +	.master_xfer	= qup_i2c_xfer, +	.functionality	= qup_i2c_func, +}; + +static void qup_i2c_enable_clocks(struct qup_i2c_dev *qup) +{ +	clk_prepare_enable(qup->clk); +	clk_prepare_enable(qup->pclk); +} + +static void qup_i2c_disable_clocks(struct qup_i2c_dev *qup) +{ +	u32 config; + +	qup_i2c_change_state(qup, QUP_RESET_STATE); +	clk_disable_unprepare(qup->clk); +	config = readl(qup->base + QUP_CONFIG); +	config |= QUP_CLOCK_AUTO_GATE; +	writel(config, qup->base + QUP_CONFIG); +	clk_disable_unprepare(qup->pclk); +} + +static int qup_i2c_probe(struct platform_device *pdev) +{ +	static const int blk_sizes[] = {4, 16, 32}; +	struct device_node *node = pdev->dev.of_node; +	struct qup_i2c_dev *qup; +	unsigned long one_bit_t; +	struct resource *res; +	u32 io_mode, hw_ver, size; +	int ret, fs_div, hs_div; +	int src_clk_freq; +	u32 clk_freq = 100000; + +	qup = devm_kzalloc(&pdev->dev, sizeof(*qup), GFP_KERNEL); +	if (!qup) +		return -ENOMEM; + +	qup->dev = &pdev->dev; +	init_completion(&qup->xfer); +	platform_set_drvdata(pdev, qup); + +	of_property_read_u32(node, "clock-frequency", &clk_freq); + +	/* We support frequencies up to FAST Mode (400KHz) */ +	if (!clk_freq || clk_freq > 400000) { +		dev_err(qup->dev, "clock frequency not supported %d\n", +			clk_freq); +		return -EINVAL; +	} + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	qup->base = devm_ioremap_resource(qup->dev, res); +	if (IS_ERR(qup->base)) +		return PTR_ERR(qup->base); + +	qup->irq = platform_get_irq(pdev, 0); +	if (qup->irq < 0) { +		dev_err(qup->dev, "No IRQ defined\n"); +		return qup->irq; +	} + +	qup->clk = devm_clk_get(qup->dev, "core"); +	if (IS_ERR(qup->clk)) { +		dev_err(qup->dev, "Could not get core clock\n"); +		return PTR_ERR(qup->clk); +	} + +	qup->pclk = devm_clk_get(qup->dev, "iface"); +	if (IS_ERR(qup->pclk)) { +		dev_err(qup->dev, "Could not get iface clock\n"); +		return PTR_ERR(qup->pclk); +	} + +	qup_i2c_enable_clocks(qup); + +	/* +	 * Bootloaders might leave a pending interrupt on certain QUP's, +	 * so we reset the core before registering for interrupts. +	 */ +	writel(1, qup->base + QUP_SW_RESET); +	ret = qup_i2c_poll_state_valid(qup); +	if (ret) +		goto fail; + +	ret = devm_request_irq(qup->dev, qup->irq, qup_i2c_interrupt, +			       IRQF_TRIGGER_HIGH, "i2c_qup", qup); +	if (ret) { +		dev_err(qup->dev, "Request %d IRQ failed\n", qup->irq); +		goto fail; +	} +	disable_irq(qup->irq); + +	hw_ver = readl(qup->base + QUP_HW_VERSION); +	dev_dbg(qup->dev, "Revision %x\n", hw_ver); + +	io_mode = readl(qup->base + QUP_IO_MODE); + +	/* +	 * The block/fifo size w.r.t. 'actual data' is 1/2 due to 'tag' +	 * associated with each byte written/received +	 */ +	size = QUP_OUTPUT_BLOCK_SIZE(io_mode); +	if (size >= ARRAY_SIZE(blk_sizes)) +		return -EIO; +	qup->out_blk_sz = blk_sizes[size] / 2; + +	size = QUP_INPUT_BLOCK_SIZE(io_mode); +	if (size >= ARRAY_SIZE(blk_sizes)) +		return -EIO; +	qup->in_blk_sz = blk_sizes[size] / 2; + +	size = QUP_OUTPUT_FIFO_SIZE(io_mode); +	qup->out_fifo_sz = qup->out_blk_sz * (2 << size); + +	size = QUP_INPUT_FIFO_SIZE(io_mode); +	qup->in_fifo_sz = qup->in_blk_sz * (2 << size); + +	src_clk_freq = clk_get_rate(qup->clk); +	fs_div = ((src_clk_freq / clk_freq) / 2) - 3; +	hs_div = 3; +	qup->clk_ctl = (hs_div << 8) | (fs_div & 0xff); + +	/* +	 * Time it takes for a byte to be clocked out on the bus. +	 * Each byte takes 9 clock cycles (8 bits + 1 ack). +	 */ +	one_bit_t = (USEC_PER_SEC / clk_freq) + 1; +	qup->one_byte_t = one_bit_t * 9; + +	dev_dbg(qup->dev, "IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n", +		qup->in_blk_sz, qup->in_fifo_sz, +		qup->out_blk_sz, qup->out_fifo_sz); + +	i2c_set_adapdata(&qup->adap, qup); +	qup->adap.algo = &qup_i2c_algo; +	qup->adap.dev.parent = qup->dev; +	qup->adap.dev.of_node = pdev->dev.of_node; +	strlcpy(qup->adap.name, "QUP I2C adapter", sizeof(qup->adap.name)); + +	ret = i2c_add_adapter(&qup->adap); +	if (ret) +		goto fail; + +	pm_runtime_set_autosuspend_delay(qup->dev, MSEC_PER_SEC); +	pm_runtime_use_autosuspend(qup->dev); +	pm_runtime_set_active(qup->dev); +	pm_runtime_enable(qup->dev); +	return 0; + +fail: +	qup_i2c_disable_clocks(qup); +	return ret; +} + +static int qup_i2c_remove(struct platform_device *pdev) +{ +	struct qup_i2c_dev *qup = platform_get_drvdata(pdev); + +	disable_irq(qup->irq); +	qup_i2c_disable_clocks(qup); +	i2c_del_adapter(&qup->adap); +	pm_runtime_disable(qup->dev); +	pm_runtime_set_suspended(qup->dev); +	return 0; +} + +#ifdef CONFIG_PM +static int qup_i2c_pm_suspend_runtime(struct device *device) +{ +	struct qup_i2c_dev *qup = dev_get_drvdata(device); + +	dev_dbg(device, "pm_runtime: suspending...\n"); +	qup_i2c_disable_clocks(qup); +	return 0; +} + +static int qup_i2c_pm_resume_runtime(struct device *device) +{ +	struct qup_i2c_dev *qup = dev_get_drvdata(device); + +	dev_dbg(device, "pm_runtime: resuming...\n"); +	qup_i2c_enable_clocks(qup); +	return 0; +} +#endif + +#ifdef CONFIG_PM_SLEEP +static int qup_i2c_suspend(struct device *device) +{ +	qup_i2c_pm_suspend_runtime(device); +	return 0; +} + +static int qup_i2c_resume(struct device *device) +{ +	qup_i2c_pm_resume_runtime(device); +	pm_runtime_mark_last_busy(device); +	pm_request_autosuspend(device); +	return 0; +} +#endif + +static const struct dev_pm_ops qup_i2c_qup_pm_ops = { +	SET_SYSTEM_SLEEP_PM_OPS( +		qup_i2c_suspend, +		qup_i2c_resume) +	SET_RUNTIME_PM_OPS( +		qup_i2c_pm_suspend_runtime, +		qup_i2c_pm_resume_runtime, +		NULL) +}; + +static const struct of_device_id qup_i2c_dt_match[] = { +	{ .compatible = "qcom,i2c-qup-v1.1.1" }, +	{ .compatible = "qcom,i2c-qup-v2.1.1" }, +	{ .compatible = "qcom,i2c-qup-v2.2.1" }, +	{} +}; +MODULE_DEVICE_TABLE(of, qup_i2c_dt_match); + +static struct platform_driver qup_i2c_driver = { +	.probe  = qup_i2c_probe, +	.remove = qup_i2c_remove, +	.driver = { +		.name = "i2c_qup", +		.owner = THIS_MODULE, +		.pm = &qup_i2c_qup_pm_ops, +		.of_match_table = qup_i2c_dt_match, +	}, +}; + +module_platform_driver(qup_i2c_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:i2c_qup"); diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index d2fe11da5e8..89940592367 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -1,7 +1,9 @@  /* - *  drivers/i2c/busses/i2c-rcar.c + * Driver for the Renesas RCar I2C unit   * - * Copyright (C) 2012 Renesas Solutions Corp. + * Copyright (C) 2014 Wolfram Sang <wsa@sang-engineering.com> + * + * Copyright (C) 2012-14 Renesas Solutions Corp.   * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>   *   * This file is based on the drivers/i2c/busses/i2c-sh7760.c @@ -12,31 +14,26 @@   *   * 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 + * the Free Software Foundation; version 2 of the License.   *   * This program is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   */  #include <linux/clk.h>  #include <linux/delay.h>  #include <linux/err.h> -#include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/io.h>  #include <linux/i2c.h>  #include <linux/i2c/i2c-rcar.h>  #include <linux/kernel.h>  #include <linux/module.h> +#include <linux/of_device.h>  #include <linux/platform_device.h>  #include <linux/pm_runtime.h>  #include <linux/slab.h> -#include <linux/spinlock.h>  /* register offsets */  #define ICSCR	0x00	/* slave ctrl */ @@ -60,7 +57,7 @@  #define FSB	(1 << 1)	/* force stop bit */  #define ESG	(1 << 0)	/* en startbit gen */ -/* ICMSR */ +/* ICMSR (also for ICMIE) */  #define MNR	(1 << 6)	/* nack received */  #define MAL	(1 << 5)	/* arbitration lost */  #define MST	(1 << 4)	/* sent a stop */ @@ -69,32 +66,18 @@  #define MDR	(1 << 1)  #define MAT	(1 << 0)	/* slave addr xfer done */ -/* ICMIE */ -#define MNRE	(1 << 6)	/* nack irq en */ -#define MALE	(1 << 5)	/* arblos irq en */ -#define MSTE	(1 << 4)	/* stop irq en */ -#define MDEE	(1 << 3) -#define MDTE	(1 << 2) -#define MDRE	(1 << 1) -#define MATE	(1 << 0)	/* address sent irq en */ +#define RCAR_BUS_PHASE_START	(MDBS | MIE | ESG) +#define RCAR_BUS_PHASE_DATA	(MDBS | MIE) +#define RCAR_BUS_PHASE_STOP	(MDBS | MIE | FSB) -enum { -	RCAR_BUS_PHASE_ADDR, -	RCAR_BUS_PHASE_DATA, -	RCAR_BUS_PHASE_STOP, -}; +#define RCAR_IRQ_SEND	(MNR | MAL | MST | MAT | MDE) +#define RCAR_IRQ_RECV	(MNR | MAL | MST | MAT | MDR) +#define RCAR_IRQ_STOP	(MST) -enum { -	RCAR_IRQ_CLOSE, -	RCAR_IRQ_OPEN_FOR_SEND, -	RCAR_IRQ_OPEN_FOR_RECV, -	RCAR_IRQ_OPEN_FOR_STOP, -}; +#define RCAR_IRQ_ACK_SEND	(~(MAT | MDE)) +#define RCAR_IRQ_ACK_RECV	(~(MAT | MDR)) -/* - * flags - */  #define ID_LAST_MSG	(1 << 0)  #define ID_IOERROR	(1 << 1)  #define ID_DONE		(1 << 2) @@ -102,23 +85,22 @@ enum {  #define ID_NACK		(1 << 4)  enum rcar_i2c_type { -	I2C_RCAR_H1, -	I2C_RCAR_H2, +	I2C_RCAR_GEN1, +	I2C_RCAR_GEN2,  };  struct rcar_i2c_priv {  	void __iomem *io;  	struct i2c_adapter adap;  	struct i2c_msg	*msg; +	struct clk *clk; -	spinlock_t lock;  	wait_queue_head_t wait;  	int pos; -	int irq;  	u32 icccr;  	u32 flags; -	enum rcar_i2c_type	devtype; +	enum rcar_i2c_type devtype;  };  #define rcar_i2c_priv_to_dev(p)		((p)->adap.dev.parent) @@ -129,9 +111,7 @@ struct rcar_i2c_priv {  #define LOOP_TIMEOUT	1024 -/* - *		basic functions - */ +  static void rcar_i2c_write(struct rcar_i2c_priv *priv, int reg, u32 val)  {  	writel(val, priv->io + reg); @@ -160,36 +140,6 @@ static void rcar_i2c_init(struct rcar_i2c_priv *priv)  	rcar_i2c_write(priv, ICMAR, 0);  } -static void rcar_i2c_irq_mask(struct rcar_i2c_priv *priv, int open) -{ -	u32 val = MNRE | MALE | MSTE | MATE; /* default */ - -	switch (open) { -	case RCAR_IRQ_OPEN_FOR_SEND: -		val |= MDEE; /* default + send */ -		break; -	case RCAR_IRQ_OPEN_FOR_RECV: -		val |= MDRE; /* default + read */ -		break; -	case RCAR_IRQ_OPEN_FOR_STOP: -		val = MSTE; /* stop irq only */ -		break; -	case RCAR_IRQ_CLOSE: -	default: -		val = 0; /* all close */ -		break; -	} -	rcar_i2c_write(priv, ICMIER, val); -} - -static void rcar_i2c_set_addr(struct rcar_i2c_priv *priv, u32 recv) -{ -	rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | recv); -} - -/* - *		bus control functions - */  static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv)  {  	int i; @@ -204,44 +154,21 @@ static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv)  	return -EBUSY;  } -static void rcar_i2c_bus_phase(struct rcar_i2c_priv *priv, int phase) -{ -	switch (phase) { -	case RCAR_BUS_PHASE_ADDR: -		rcar_i2c_write(priv, ICMCR, MDBS | MIE | ESG); -		break; -	case RCAR_BUS_PHASE_DATA: -		rcar_i2c_write(priv, ICMCR, MDBS | MIE); -		break; -	case RCAR_BUS_PHASE_STOP: -		rcar_i2c_write(priv, ICMCR, MDBS | MIE | FSB); -		break; -	} -} - -/* - *		clock function - */  static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,  				    u32 bus_speed,  				    struct device *dev)  { -	struct clk *clkp = clk_get(NULL, "peripheral_clk");  	u32 scgd, cdf;  	u32 round, ick;  	u32 scl;  	u32 cdf_width; - -	if (!clkp) { -		dev_err(dev, "there is no peripheral_clk\n"); -		return -EIO; -	} +	unsigned long rate;  	switch (priv->devtype) { -	case I2C_RCAR_H1: +	case I2C_RCAR_GEN1:  		cdf_width = 2;  		break; -	case I2C_RCAR_H2: +	case I2C_RCAR_GEN2:  		cdf_width = 3;  		break;  	default: @@ -264,15 +191,14 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,  	 * clkp : peripheral_clk  	 * F[]  : integer up-valuation  	 */ -	for (cdf = 0; cdf < (1 << cdf_width); cdf++) { -		ick = clk_get_rate(clkp) / (1 + cdf); -		if (ick < 20000000) -			goto ick_find; +	rate = clk_get_rate(priv->clk); +	cdf = rate / 20000000; +	if (cdf >= 1 << cdf_width) { +		dev_err(dev, "Input clock %lu too high\n", rate); +		return -EIO;  	} -	dev_err(dev, "there is no best CDF\n"); -	return -EIO; +	ick = rate / (cdf + 1); -ick_find:  	/*  	 * it is impossible to calculate large scale  	 * number on u32. separate it @@ -290,6 +216,12 @@ ick_find:  	 *  	 * Calculation result (= SCL) should be less than  	 * bus_speed for hardware safety +	 * +	 * We could use something along the lines of +	 *	div = ick / (bus_speed + 1) + 1; +	 *	scgd = (div - 20 - round + 7) / 8; +	 *	scl = ick / (20 + (scgd * 8) + round); +	 * (not fully verified) but that would get pretty involved  	 */  	for (scgd = 0; scgd < 0x40; scgd++) {  		scl = ick / (20 + (scgd * 8) + round); @@ -301,70 +233,28 @@ ick_find:  scgd_find:  	dev_dbg(dev, "clk %d/%d(%lu), round %u, CDF:0x%x, SCGD: 0x%x\n", -		scl, bus_speed, clk_get_rate(clkp), round, cdf, scgd); +		scl, bus_speed, clk_get_rate(priv->clk), round, cdf, scgd);  	/*  	 * keep icccr value  	 */ -	priv->icccr = (scgd << (cdf_width) | cdf); - -	return 0; -} - -static void rcar_i2c_clock_start(struct rcar_i2c_priv *priv) -{ -	rcar_i2c_write(priv, ICCCR, priv->icccr); -} - -/* - *		status functions - */ -static u32 rcar_i2c_status_get(struct rcar_i2c_priv *priv) -{ -	return rcar_i2c_read(priv, ICMSR); -} - -#define rcar_i2c_status_clear(priv) rcar_i2c_status_bit_clear(priv, 0xffffffff) -static void rcar_i2c_status_bit_clear(struct rcar_i2c_priv *priv, u32 bit) -{ -	rcar_i2c_write(priv, ICMSR, ~bit); -} - -/* - *		recv/send functions - */ -static int rcar_i2c_recv(struct rcar_i2c_priv *priv) -{ -	rcar_i2c_set_addr(priv, 1); -	rcar_i2c_status_clear(priv); -	rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_ADDR); -	rcar_i2c_irq_mask(priv, RCAR_IRQ_OPEN_FOR_RECV); +	priv->icccr = scgd << cdf_width | cdf;  	return 0;  } -static int rcar_i2c_send(struct rcar_i2c_priv *priv) +static int rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)  { -	int ret; - -	/* -	 * It should check bus status when send case -	 */ -	ret = rcar_i2c_bus_barrier(priv); -	if (ret < 0) -		return ret; +	int read = !!rcar_i2c_is_recv(priv); -	rcar_i2c_set_addr(priv, 0); -	rcar_i2c_status_clear(priv); -	rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_ADDR); -	rcar_i2c_irq_mask(priv, RCAR_IRQ_OPEN_FOR_SEND); +	rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | read); +	rcar_i2c_write(priv, ICMSR, 0); +	rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START); +	rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND);  	return 0;  } -#define rcar_i2c_send_restart(priv) rcar_i2c_status_bit_clear(priv, (MAT | MDE)) -#define rcar_i2c_recv_restart(priv) rcar_i2c_status_bit_clear(priv, (MAT | MDR)) -  /*   *		interrupt functions   */ @@ -385,7 +275,7 @@ static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr)  	 * goto data phase.  	 */  	if (msr & MAT) -		rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_DATA); +		rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA);  	if (priv->pos < msg->len) {  		/* @@ -413,7 +303,7 @@ static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr)  			 * prepare stop condition here.  			 * ID_DONE will be set on STOP irq.  			 */ -			rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_STOP); +			rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);  		else  			/*  			 * If current msg is _NOT_ last msg, @@ -424,7 +314,7 @@ static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr)  			return ID_DONE;  	} -	rcar_i2c_send_restart(priv); +	rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_SEND);  	return 0;  } @@ -461,11 +351,11 @@ static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)  	 * otherwise, go to DATA phase.  	 */  	if (priv->pos + 1 >= msg->len) -		rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_STOP); +		rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);  	else -		rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_DATA); +		rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); -	rcar_i2c_recv_restart(priv); +	rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_RECV);  	return 0;  } @@ -473,53 +363,31 @@ static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)  static irqreturn_t rcar_i2c_irq(int irq, void *ptr)  {  	struct rcar_i2c_priv *priv = ptr; -	struct device *dev = rcar_i2c_priv_to_dev(priv);  	u32 msr; -	/*-------------- spin lock -----------------*/ -	spin_lock(&priv->lock); - -	msr = rcar_i2c_status_get(priv); +	msr = rcar_i2c_read(priv, ICMSR); -	/* -	 * Arbitration lost -	 */ +	/* Arbitration lost */  	if (msr & MAL) { -		/* -		 * CAUTION -		 * -		 * When arbitration lost, device become _slave_ mode. -		 */ -		dev_dbg(dev, "Arbitration Lost\n");  		rcar_i2c_flags_set(priv, (ID_DONE | ID_ARBLOST));  		goto out;  	} -	/* -	 * Stop -	 */ +	/* Stop */  	if (msr & MST) { -		dev_dbg(dev, "Stop\n");  		rcar_i2c_flags_set(priv, ID_DONE);  		goto out;  	} -	/* -	 * Nack -	 */ +	/* Nack */  	if (msr & MNR) { -		dev_dbg(dev, "Nack\n"); -  		/* go to stop phase */ -		rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_STOP); -		rcar_i2c_irq_mask(priv, RCAR_IRQ_OPEN_FOR_STOP); +		rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP); +		rcar_i2c_write(priv, ICMIER, RCAR_IRQ_STOP);  		rcar_i2c_flags_set(priv, ID_NACK);  		goto out;  	} -	/* -	 * recv/send -	 */  	if (rcar_i2c_is_recv(priv))  		rcar_i2c_flags_set(priv, rcar_i2c_irq_recv(priv, msr));  	else @@ -527,14 +395,11 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr)  out:  	if (rcar_i2c_flags_has(priv, ID_DONE)) { -		rcar_i2c_irq_mask(priv, RCAR_IRQ_CLOSE); -		rcar_i2c_status_clear(priv); +		rcar_i2c_write(priv, ICMIER, 0); +		rcar_i2c_write(priv, ICMSR, 0);  		wake_up(&priv->wait);  	} -	spin_unlock(&priv->lock); -	/*-------------- spin unlock -----------------*/ -  	return IRQ_HANDLED;  } @@ -544,24 +409,24 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,  {  	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);  	struct device *dev = rcar_i2c_priv_to_dev(priv); -	unsigned long flags;  	int i, ret, timeout;  	pm_runtime_get_sync(dev); -	/*-------------- spin lock -----------------*/ -	spin_lock_irqsave(&priv->lock, flags); -  	rcar_i2c_init(priv); -	rcar_i2c_clock_start(priv); +	/* start clock */ +	rcar_i2c_write(priv, ICCCR, priv->icccr); -	spin_unlock_irqrestore(&priv->lock, flags); -	/*-------------- spin unlock -----------------*/ +	ret = rcar_i2c_bus_barrier(priv); +	if (ret < 0) +		goto out; -	ret = -EINVAL;  	for (i = 0; i < num; i++) { -		/*-------------- spin lock -----------------*/ -		spin_lock_irqsave(&priv->lock, flags); +		/* This HW can't send STOP after address phase */ +		if (msgs[i].len == 0) { +			ret = -EOPNOTSUPP; +			break; +		}  		/* init each data */  		priv->msg	= &msgs[i]; @@ -570,21 +435,11 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,  		if (priv->msg == &msgs[num - 1])  			rcar_i2c_flags_set(priv, ID_LAST_MSG); -		/* start send/recv */ -		if (rcar_i2c_is_recv(priv)) -			ret = rcar_i2c_recv(priv); -		else -			ret = rcar_i2c_send(priv); - -		spin_unlock_irqrestore(&priv->lock, flags); -		/*-------------- spin unlock -----------------*/ +		ret = rcar_i2c_prepare_msg(priv);  		if (ret < 0)  			break; -		/* -		 * wait result -		 */  		timeout = wait_event_timeout(priv->wait,  					     rcar_i2c_flags_has(priv, ID_DONE),  					     5 * HZ); @@ -593,11 +448,8 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,  			break;  		} -		/* -		 * error handling -		 */  		if (rcar_i2c_flags_has(priv, ID_NACK)) { -			ret = -EREMOTEIO; +			ret = -ENXIO;  			break;  		} @@ -613,10 +465,10 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,  		ret = i + 1; /* The number of transfer */  	} - +out:  	pm_runtime_put(dev); -	if (ret < 0) +	if (ret < 0 && ret != -ENXIO)  		dev_err(dev, "error %d : %x\n", ret, priv->flags);  	return ret; @@ -624,7 +476,8 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,  static u32 rcar_i2c_func(struct i2c_adapter *adap)  { -	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +	/* This HW can't do SMBUS_QUICK and NOSTART */ +	return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);  }  static const struct i2c_algorithm rcar_i2c_algo = { @@ -632,6 +485,19 @@ static const struct i2c_algorithm rcar_i2c_algo = {  	.functionality	= rcar_i2c_func,  }; +static const struct of_device_id rcar_i2c_dt_ids[] = { +	{ .compatible = "renesas,i2c-rcar", .data = (void *)I2C_RCAR_GEN1 }, +	{ .compatible = "renesas,i2c-r8a7778", .data = (void *)I2C_RCAR_GEN1 }, +	{ .compatible = "renesas,i2c-r8a7779", .data = (void *)I2C_RCAR_GEN1 }, +	{ .compatible = "renesas,i2c-r8a7790", .data = (void *)I2C_RCAR_GEN2 }, +	{ .compatible = "renesas,i2c-r8a7791", .data = (void *)I2C_RCAR_GEN2 }, +	{ .compatible = "renesas,i2c-r8a7792", .data = (void *)I2C_RCAR_GEN2 }, +	{ .compatible = "renesas,i2c-r8a7793", .data = (void *)I2C_RCAR_GEN2 }, +	{ .compatible = "renesas,i2c-r8a7794", .data = (void *)I2C_RCAR_GEN2 }, +	{}, +}; +MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids); +  static int rcar_i2c_probe(struct platform_device *pdev)  {  	struct i2c_rcar_platform_data *pdata = dev_get_platdata(&pdev->dev); @@ -640,19 +506,28 @@ static int rcar_i2c_probe(struct platform_device *pdev)  	struct resource *res;  	struct device *dev = &pdev->dev;  	u32 bus_speed; -	int ret; +	int irq, ret;  	priv = devm_kzalloc(dev, sizeof(struct rcar_i2c_priv), GFP_KERNEL); -	if (!priv) { -		dev_err(dev, "no mem for private data\n"); +	if (!priv)  		return -ENOMEM; + +	priv->clk = devm_clk_get(dev, NULL); +	if (IS_ERR(priv->clk)) { +		dev_err(dev, "cannot get clock\n"); +		return PTR_ERR(priv->clk);  	}  	bus_speed = 100000; /* default 100 kHz */ -	if (pdata && pdata->bus_speed) +	ret = of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed); +	if (ret < 0 && pdata && pdata->bus_speed)  		bus_speed = pdata->bus_speed; -	priv->devtype = platform_get_device_id(pdev)->driver_data; +	if (pdev->dev.of_node) +		priv->devtype = (long)of_match_device(rcar_i2c_dt_ids, +						      dev)->data; +	else +		priv->devtype = platform_get_device_id(pdev)->driver_data;  	ret = rcar_i2c_clock_calculate(priv, bus_speed, dev);  	if (ret < 0) @@ -663,23 +538,23 @@ static int rcar_i2c_probe(struct platform_device *pdev)  	if (IS_ERR(priv->io))  		return PTR_ERR(priv->io); -	priv->irq = platform_get_irq(pdev, 0); +	irq = platform_get_irq(pdev, 0);  	init_waitqueue_head(&priv->wait); -	spin_lock_init(&priv->lock);  	adap			= &priv->adap;  	adap->nr		= pdev->id;  	adap->algo		= &rcar_i2c_algo; -	adap->class		= I2C_CLASS_HWMON | I2C_CLASS_SPD; +	adap->class		= I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED;  	adap->retries		= 3;  	adap->dev.parent	= dev; +	adap->dev.of_node	= dev->of_node;  	i2c_set_adapdata(adap, priv);  	strlcpy(adap->name, pdev->name, sizeof(adap->name)); -	ret = devm_request_irq(dev, priv->irq, rcar_i2c_irq, 0, +	ret = devm_request_irq(dev, irq, rcar_i2c_irq, 0,  			       dev_name(dev), priv);  	if (ret < 0) { -		dev_err(dev, "cannot get irq %d\n", priv->irq); +		dev_err(dev, "cannot get irq %d\n", irq);  		return ret;  	} @@ -709,9 +584,9 @@ static int rcar_i2c_remove(struct platform_device *pdev)  }  static struct platform_device_id rcar_i2c_id_table[] = { -	{ "i2c-rcar",		I2C_RCAR_H1 }, -	{ "i2c-rcar_h1",	I2C_RCAR_H1 }, -	{ "i2c-rcar_h2",	I2C_RCAR_H2 }, +	{ "i2c-rcar",		I2C_RCAR_GEN1 }, +	{ "i2c-rcar_gen1",	I2C_RCAR_GEN1 }, +	{ "i2c-rcar_gen2",	I2C_RCAR_GEN2 },  	{},  };  MODULE_DEVICE_TABLE(platform, rcar_i2c_id_table); @@ -720,6 +595,7 @@ static struct platform_driver rcar_i2c_driver = {  	.driver	= {  		.name	= "i2c-rcar",  		.owner	= THIS_MODULE, +		.of_match_table = rcar_i2c_dt_ids,  	},  	.probe		= rcar_i2c_probe,  	.remove		= rcar_i2c_remove, @@ -728,6 +604,6 @@ static struct platform_driver rcar_i2c_driver = {  module_platform_driver(rcar_i2c_driver); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2");  MODULE_DESCRIPTION("Renesas R-Car I2C bus driver");  MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); diff --git a/drivers/i2c/busses/i2c-riic.c b/drivers/i2c/busses/i2c-riic.c new file mode 100644 index 00000000000..af3b3d032a9 --- /dev/null +++ b/drivers/i2c/busses/i2c-riic.c @@ -0,0 +1,427 @@ +/* + * Renesas RIIC driver + * + * Copyright (C) 2013 Wolfram Sang <wsa@sang-engineering.com> + * Copyright (C) 2013 Renesas Solutions Corp. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +/* + * This i2c core has a lot of interrupts, namely 8. We use their chaining as + * some kind of state machine. + * + * 1) The main xfer routine kicks off a transmission by putting the start bit + * (or repeated start) on the bus and enabling the transmit interrupt (TIE) + * since we need to send the slave address + RW bit in every case. + * + * 2) TIE sends slave address + RW bit and selects how to continue. + * + * 3a) Write case: We keep utilizing TIE as long as we have data to send. If we + * are done, we switch over to the transmission done interrupt (TEIE) and mark + * the message as completed (includes sending STOP) there. + * + * 3b) Read case: We switch over to receive interrupt (RIE). One dummy read is + * needed to start clocking, then we keep receiving until we are done. Note + * that we use the RDRFS mode all the time, i.e. we ACK/NACK every byte by + * writing to the ACKBT bit. I tried using the RDRFS mode only at the end of a + * message to create the final NACK as sketched in the datasheet. This caused + * some subtle races (when byte n was processed and byte n+1 was already + * waiting), though, and I started with the safe approach. + * + * 4) If we got a NACK somewhere, we flag the error and stop the transmission + * via NAKIE. + * + * Also check the comments in the interrupt routines for some gory details. + */ + +#include <linux/clk.h> +#include <linux/completion.h> +#include <linux/err.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> + +#define RIIC_ICCR1	0x00 +#define RIIC_ICCR2	0x04 +#define RIIC_ICMR1	0x08 +#define RIIC_ICMR3	0x10 +#define RIIC_ICSER	0x18 +#define RIIC_ICIER	0x1c +#define RIIC_ICSR2	0x24 +#define RIIC_ICBRL	0x34 +#define RIIC_ICBRH	0x38 +#define RIIC_ICDRT	0x3c +#define RIIC_ICDRR	0x40 + +#define ICCR1_ICE	0x80 +#define ICCR1_IICRST	0x40 +#define ICCR1_SOWP	0x10 + +#define ICCR2_BBSY	0x80 +#define ICCR2_SP	0x08 +#define ICCR2_RS	0x04 +#define ICCR2_ST	0x02 + +#define ICMR1_CKS_MASK	0x70 +#define ICMR1_BCWP	0x08 +#define ICMR1_CKS(_x)	((((_x) << 4) & ICMR1_CKS_MASK) | ICMR1_BCWP) + +#define ICMR3_RDRFS	0x20 +#define ICMR3_ACKWP	0x10 +#define ICMR3_ACKBT	0x08 + +#define ICIER_TIE	0x80 +#define ICIER_TEIE	0x40 +#define ICIER_RIE	0x20 +#define ICIER_NAKIE	0x10 + +#define ICSR2_NACKF	0x10 + +/* ICBRx (@ PCLK 33MHz) */ +#define ICBR_RESERVED	0xe0 /* Should be 1 on writes */ +#define ICBRL_SP100K	(19 | ICBR_RESERVED) +#define ICBRH_SP100K	(16 | ICBR_RESERVED) +#define ICBRL_SP400K	(21 | ICBR_RESERVED) +#define ICBRH_SP400K	(9 | ICBR_RESERVED) + +#define RIIC_INIT_MSG	-1 + +struct riic_dev { +	void __iomem *base; +	u8 *buf; +	struct i2c_msg *msg; +	int bytes_left; +	int err; +	int is_last; +	struct completion msg_done; +	struct i2c_adapter adapter; +	struct clk *clk; +}; + +struct riic_irq_desc { +	int res_num; +	irq_handler_t isr; +	char *name; +}; + +static inline void riic_clear_set_bit(struct riic_dev *riic, u8 clear, u8 set, u8 reg) +{ +	writeb((readb(riic->base + reg) & ~clear) | set, riic->base + reg); +} + +static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) +{ +	struct riic_dev *riic = i2c_get_adapdata(adap); +	unsigned long time_left; +	int i, ret; +	u8 start_bit; + +	ret = clk_prepare_enable(riic->clk); +	if (ret) +		return ret; + +	if (readb(riic->base + RIIC_ICCR2) & ICCR2_BBSY) { +		riic->err = -EBUSY; +		goto out; +	} + +	reinit_completion(&riic->msg_done); +	riic->err = 0; + +	writeb(0, riic->base + RIIC_ICSR2); + +	for (i = 0, start_bit = ICCR2_ST; i < num; i++) { +		riic->bytes_left = RIIC_INIT_MSG; +		riic->buf = msgs[i].buf; +		riic->msg = &msgs[i]; +		riic->is_last = (i == num - 1); + +		writeb(ICIER_NAKIE | ICIER_TIE, riic->base + RIIC_ICIER); + +		writeb(start_bit, riic->base + RIIC_ICCR2); + +		time_left = wait_for_completion_timeout(&riic->msg_done, riic->adapter.timeout); +		if (time_left == 0) +			riic->err = -ETIMEDOUT; + +		if (riic->err) +			break; + +		start_bit = ICCR2_RS; +	} + + out: +	clk_disable_unprepare(riic->clk); + +	return riic->err ?: num; +} + +static irqreturn_t riic_tdre_isr(int irq, void *data) +{ +	struct riic_dev *riic = data; +	u8 val; + +	if (!riic->bytes_left) +		return IRQ_NONE; + +	if (riic->bytes_left == RIIC_INIT_MSG) { +		val = !!(riic->msg->flags & I2C_M_RD); +		if (val) +			/* On read, switch over to receive interrupt */ +			riic_clear_set_bit(riic, ICIER_TIE, ICIER_RIE, RIIC_ICIER); +		else +			/* On write, initialize length */ +			riic->bytes_left = riic->msg->len; + +		val |= (riic->msg->addr << 1); +	} else { +		val = *riic->buf; +		riic->buf++; +		riic->bytes_left--; +	} + +	/* +	 * Switch to transmission ended interrupt when done. Do check here +	 * after bytes_left was initialized to support SMBUS_QUICK (new msg has +	 * 0 length then) +	 */ +	if (riic->bytes_left == 0) +		riic_clear_set_bit(riic, ICIER_TIE, ICIER_TEIE, RIIC_ICIER); + +	/* +	 * This acks the TIE interrupt. We get another TIE immediately if our +	 * value could be moved to the shadow shift register right away. So +	 * this must be after updates to ICIER (where we want to disable TIE)! +	 */ +	writeb(val, riic->base + RIIC_ICDRT); + +	return IRQ_HANDLED; +} + +static irqreturn_t riic_tend_isr(int irq, void *data) +{ +	struct riic_dev *riic = data; + +	if (readb(riic->base + RIIC_ICSR2) & ICSR2_NACKF) { +		/* We got a NACKIE */ +		readb(riic->base + RIIC_ICDRR);	/* dummy read */ +		riic->err = -ENXIO; +	} else if (riic->bytes_left) { +		return IRQ_NONE; +	} + +	if (riic->is_last || riic->err) +		writeb(ICCR2_SP, riic->base + RIIC_ICCR2); + +	writeb(0, riic->base + RIIC_ICIER); +	complete(&riic->msg_done); + +	return IRQ_HANDLED; +} + +static irqreturn_t riic_rdrf_isr(int irq, void *data) +{ +	struct riic_dev *riic = data; + +	if (!riic->bytes_left) +		return IRQ_NONE; + +	if (riic->bytes_left == RIIC_INIT_MSG) { +		riic->bytes_left = riic->msg->len; +		readb(riic->base + RIIC_ICDRR);	/* dummy read */ +		return IRQ_HANDLED; +	} + +	if (riic->bytes_left == 1) { +		/* STOP must come before we set ACKBT! */ +		if (riic->is_last) +			writeb(ICCR2_SP, riic->base + RIIC_ICCR2); + +		riic_clear_set_bit(riic, 0, ICMR3_ACKBT, RIIC_ICMR3); + +		writeb(0, riic->base + RIIC_ICIER); +		complete(&riic->msg_done); +	} else { +		riic_clear_set_bit(riic, ICMR3_ACKBT, 0, RIIC_ICMR3); +	} + +	/* Reading acks the RIE interrupt */ +	*riic->buf = readb(riic->base + RIIC_ICDRR); +	riic->buf++; +	riic->bytes_left--; + +	return IRQ_HANDLED; +} + +static u32 riic_func(struct i2c_adapter *adap) +{ +	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm riic_algo = { +	.master_xfer	= riic_xfer, +	.functionality	= riic_func, +}; + +static int riic_init_hw(struct riic_dev *riic, u32 spd) +{ +	int ret; +	unsigned long rate; + +	ret = clk_prepare_enable(riic->clk); +	if (ret) +		return ret; + +	/* +	 * TODO: Implement formula to calculate the timing values depending on +	 * variable parent clock rate and arbitrary bus speed +	 */ +	rate = clk_get_rate(riic->clk); +	if (rate != 33325000) { +		dev_err(&riic->adapter.dev, +			"invalid parent clk (%lu). Must be 33325000Hz\n", rate); +		clk_disable_unprepare(riic->clk); +		return -EINVAL; +	} + +	/* Changing the order of accessing IICRST and ICE may break things! */ +	writeb(ICCR1_IICRST | ICCR1_SOWP, riic->base + RIIC_ICCR1); +	riic_clear_set_bit(riic, 0, ICCR1_ICE, RIIC_ICCR1); + +	switch (spd) { +	case 100000: +		writeb(ICMR1_CKS(3), riic->base + RIIC_ICMR1); +		writeb(ICBRH_SP100K, riic->base + RIIC_ICBRH); +		writeb(ICBRL_SP100K, riic->base + RIIC_ICBRL); +		break; +	case 400000: +		writeb(ICMR1_CKS(1), riic->base + RIIC_ICMR1); +		writeb(ICBRH_SP400K, riic->base + RIIC_ICBRH); +		writeb(ICBRL_SP400K, riic->base + RIIC_ICBRL); +		break; +	default: +		dev_err(&riic->adapter.dev, +			"unsupported bus speed (%dHz). Use 100000 or 400000\n", spd); +		clk_disable_unprepare(riic->clk); +		return -EINVAL; +	} + +	writeb(0, riic->base + RIIC_ICSER); +	writeb(ICMR3_ACKWP | ICMR3_RDRFS, riic->base + RIIC_ICMR3); + +	riic_clear_set_bit(riic, ICCR1_IICRST, 0, RIIC_ICCR1); + +	clk_disable_unprepare(riic->clk); + +	return 0; +} + +static struct riic_irq_desc riic_irqs[] = { +	{ .res_num = 0, .isr = riic_tend_isr, .name = "riic-tend" }, +	{ .res_num = 1, .isr = riic_rdrf_isr, .name = "riic-rdrf" }, +	{ .res_num = 2, .isr = riic_tdre_isr, .name = "riic-tdre" }, +	{ .res_num = 5, .isr = riic_tend_isr, .name = "riic-nack" }, +}; + +static int riic_i2c_probe(struct platform_device *pdev) +{ +	struct device_node *np = pdev->dev.of_node; +	struct riic_dev *riic; +	struct i2c_adapter *adap; +	struct resource *res; +	u32 bus_rate = 0; +	int i, ret; + +	riic = devm_kzalloc(&pdev->dev, sizeof(*riic), GFP_KERNEL); +	if (!riic) +		return -ENOMEM; + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	riic->base = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(riic->base)) +		return PTR_ERR(riic->base); + +	riic->clk = devm_clk_get(&pdev->dev, NULL); +	if (IS_ERR(riic->clk)) { +		dev_err(&pdev->dev, "missing controller clock"); +		return PTR_ERR(riic->clk); +	} + +	for (i = 0; i < ARRAY_SIZE(riic_irqs); i++) { +		res = platform_get_resource(pdev, IORESOURCE_IRQ, riic_irqs[i].res_num); +		if (!res) +			return -ENODEV; + +		ret = devm_request_irq(&pdev->dev, res->start, riic_irqs[i].isr, +					0, riic_irqs[i].name, riic); +		if (ret) { +			dev_err(&pdev->dev, "failed to request irq %s\n", riic_irqs[i].name); +			return ret; +		} +	} + +	adap = &riic->adapter; +	i2c_set_adapdata(adap, riic); +	strlcpy(adap->name, "Renesas RIIC adapter", sizeof(adap->name)); +	adap->owner = THIS_MODULE; +	adap->algo = &riic_algo; +	adap->dev.parent = &pdev->dev; +	adap->dev.of_node = pdev->dev.of_node; + +	init_completion(&riic->msg_done); + +	of_property_read_u32(np, "clock-frequency", &bus_rate); +	ret = riic_init_hw(riic, bus_rate); +	if (ret) +		return ret; + + +	ret = i2c_add_adapter(adap); +	if (ret) { +		dev_err(&pdev->dev, "failed to add adapter\n"); +		return ret; +	} + +	platform_set_drvdata(pdev, riic); + +	dev_info(&pdev->dev, "registered with %dHz bus speed\n", bus_rate); +	return 0; +} + +static int riic_i2c_remove(struct platform_device *pdev) +{ +	struct riic_dev *riic = platform_get_drvdata(pdev); + +	writeb(0, riic->base + RIIC_ICIER); +	i2c_del_adapter(&riic->adapter); + +	return 0; +} + +static const struct of_device_id riic_i2c_dt_ids[] = { +	{ .compatible = "renesas,riic-rz" }, +	{ /* Sentinel */ }, +}; + +static struct platform_driver riic_i2c_driver = { +	.probe		= riic_i2c_probe, +	.remove		= riic_i2c_remove, +	.driver		= { +		.name	= "i2c-riic", +		.owner	= THIS_MODULE, +		.of_match_table = riic_i2c_dt_ids, +	}, +}; + +module_platform_driver(riic_i2c_driver); + +MODULE_DESCRIPTION("Renesas RIIC adapter"); +MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>"); +MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(of, riic_i2c_dt_ids); diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c new file mode 100644 index 00000000000..a9791509966 --- /dev/null +++ b/drivers/i2c/busses/i2c-rk3x.c @@ -0,0 +1,763 @@ +/* + * Driver for I2C adapter in Rockchip RK3xxx SoC + * + * Max Schwarz <max.schwarz@online.de> + * based on the patches by Rockchip Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/spinlock.h> +#include <linux/clk.h> +#include <linux/wait.h> +#include <linux/mfd/syscon.h> +#include <linux/regmap.h> + + +/* Register Map */ +#define REG_CON        0x00 /* control register */ +#define REG_CLKDIV     0x04 /* clock divisor register */ +#define REG_MRXADDR    0x08 /* slave address for REGISTER_TX */ +#define REG_MRXRADDR   0x0c /* slave register address for REGISTER_TX */ +#define REG_MTXCNT     0x10 /* number of bytes to be transmitted */ +#define REG_MRXCNT     0x14 /* number of bytes to be received */ +#define REG_IEN        0x18 /* interrupt enable */ +#define REG_IPD        0x1c /* interrupt pending */ +#define REG_FCNT       0x20 /* finished count */ + +/* Data buffer offsets */ +#define TXBUFFER_BASE 0x100 +#define RXBUFFER_BASE 0x200 + +/* REG_CON bits */ +#define REG_CON_EN        BIT(0) +enum { +	REG_CON_MOD_TX = 0,      /* transmit data */ +	REG_CON_MOD_REGISTER_TX, /* select register and restart */ +	REG_CON_MOD_RX,          /* receive data */ +	REG_CON_MOD_REGISTER_RX, /* broken: transmits read addr AND writes +				  * register addr */ +}; +#define REG_CON_MOD(mod)  ((mod) << 1) +#define REG_CON_MOD_MASK  (BIT(1) | BIT(2)) +#define REG_CON_START     BIT(3) +#define REG_CON_STOP      BIT(4) +#define REG_CON_LASTACK   BIT(5) /* 1: send NACK after last received byte */ +#define REG_CON_ACTACK    BIT(6) /* 1: stop if NACK is received */ + +/* REG_MRXADDR bits */ +#define REG_MRXADDR_VALID(x) BIT(24 + (x)) /* [x*8+7:x*8] of MRX[R]ADDR valid */ + +/* REG_IEN/REG_IPD bits */ +#define REG_INT_BTF       BIT(0) /* a byte was transmitted */ +#define REG_INT_BRF       BIT(1) /* a byte was received */ +#define REG_INT_MBTF      BIT(2) /* master data transmit finished */ +#define REG_INT_MBRF      BIT(3) /* master data receive finished */ +#define REG_INT_START     BIT(4) /* START condition generated */ +#define REG_INT_STOP      BIT(5) /* STOP condition generated */ +#define REG_INT_NAKRCV    BIT(6) /* NACK received */ +#define REG_INT_ALL       0x7f + +/* Constants */ +#define WAIT_TIMEOUT      200 /* ms */ +#define DEFAULT_SCL_RATE  (100 * 1000) /* Hz */ + +enum rk3x_i2c_state { +	STATE_IDLE, +	STATE_START, +	STATE_READ, +	STATE_WRITE, +	STATE_STOP +}; + +/** + * @grf_offset: offset inside the grf regmap for setting the i2c type + */ +struct rk3x_i2c_soc_data { +	int grf_offset; +}; + +struct rk3x_i2c { +	struct i2c_adapter adap; +	struct device *dev; +	struct rk3x_i2c_soc_data *soc_data; + +	/* Hardware resources */ +	void __iomem *regs; +	struct clk *clk; + +	/* Settings */ +	unsigned int scl_frequency; + +	/* Synchronization & notification */ +	spinlock_t lock; +	wait_queue_head_t wait; +	bool busy; + +	/* Current message */ +	struct i2c_msg *msg; +	u8 addr; +	unsigned int mode; +	bool is_last_msg; + +	/* I2C state machine */ +	enum rk3x_i2c_state state; +	unsigned int processed; /* sent/received bytes */ +	int error; +}; + +static inline void i2c_writel(struct rk3x_i2c *i2c, u32 value, +			      unsigned int offset) +{ +	writel(value, i2c->regs + offset); +} + +static inline u32 i2c_readl(struct rk3x_i2c *i2c, unsigned int offset) +{ +	return readl(i2c->regs + offset); +} + +/* Reset all interrupt pending bits */ +static inline void rk3x_i2c_clean_ipd(struct rk3x_i2c *i2c) +{ +	i2c_writel(i2c, REG_INT_ALL, REG_IPD); +} + +/** + * Generate a START condition, which triggers a REG_INT_START interrupt. + */ +static void rk3x_i2c_start(struct rk3x_i2c *i2c) +{ +	u32 val; + +	rk3x_i2c_clean_ipd(i2c); +	i2c_writel(i2c, REG_INT_START, REG_IEN); + +	/* enable adapter with correct mode, send START condition */ +	val = REG_CON_EN | REG_CON_MOD(i2c->mode) | REG_CON_START; + +	/* if we want to react to NACK, set ACTACK bit */ +	if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) +		val |= REG_CON_ACTACK; + +	i2c_writel(i2c, val, REG_CON); +} + +/** + * Generate a STOP condition, which triggers a REG_INT_STOP interrupt. + * + * @error: Error code to return in rk3x_i2c_xfer + */ +static void rk3x_i2c_stop(struct rk3x_i2c *i2c, int error) +{ +	unsigned int ctrl; + +	i2c->processed = 0; +	i2c->msg = NULL; +	i2c->error = error; + +	if (i2c->is_last_msg) { +		/* Enable stop interrupt */ +		i2c_writel(i2c, REG_INT_STOP, REG_IEN); + +		i2c->state = STATE_STOP; + +		ctrl = i2c_readl(i2c, REG_CON); +		ctrl |= REG_CON_STOP; +		i2c_writel(i2c, ctrl, REG_CON); +	} else { +		/* Signal rk3x_i2c_xfer to start the next message. */ +		i2c->busy = false; +		i2c->state = STATE_IDLE; + +		/* +		 * The HW is actually not capable of REPEATED START. But we can +		 * get the intended effect by resetting its internal state +		 * and issuing an ordinary START. +		 */ +		i2c_writel(i2c, 0, REG_CON); + +		/* signal that we are finished with the current msg */ +		wake_up(&i2c->wait); +	} +} + +/** + * Setup a read according to i2c->msg + */ +static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c) +{ +	unsigned int len = i2c->msg->len - i2c->processed; +	u32 con; + +	con = i2c_readl(i2c, REG_CON); + +	/* +	 * The hw can read up to 32 bytes at a time. If we need more than one +	 * chunk, send an ACK after the last byte of the current chunk. +	 */ +	if (unlikely(len > 32)) { +		len = 32; +		con &= ~REG_CON_LASTACK; +	} else { +		con |= REG_CON_LASTACK; +	} + +	/* make sure we are in plain RX mode if we read a second chunk */ +	if (i2c->processed != 0) { +		con &= ~REG_CON_MOD_MASK; +		con |= REG_CON_MOD(REG_CON_MOD_RX); +	} + +	i2c_writel(i2c, con, REG_CON); +	i2c_writel(i2c, len, REG_MRXCNT); +} + +/** + * Fill the transmit buffer with data from i2c->msg + */ +static void rk3x_i2c_fill_transmit_buf(struct rk3x_i2c *i2c) +{ +	unsigned int i, j; +	u32 cnt = 0; +	u32 val; +	u8 byte; + +	for (i = 0; i < 8; ++i) { +		val = 0; +		for (j = 0; j < 4; ++j) { +			if (i2c->processed == i2c->msg->len) +				break; + +			if (i2c->processed == 0 && cnt == 0) +				byte = (i2c->addr & 0x7f) << 1; +			else +				byte = i2c->msg->buf[i2c->processed++]; + +			val |= byte << (j * 8); +			cnt++; +		} + +		i2c_writel(i2c, val, TXBUFFER_BASE + 4 * i); + +		if (i2c->processed == i2c->msg->len) +			break; +	} + +	i2c_writel(i2c, cnt, REG_MTXCNT); +} + + +/* IRQ handlers for individual states */ + +static void rk3x_i2c_handle_start(struct rk3x_i2c *i2c, unsigned int ipd) +{ +	if (!(ipd & REG_INT_START)) { +		rk3x_i2c_stop(i2c, -EIO); +		dev_warn(i2c->dev, "unexpected irq in START: 0x%x\n", ipd); +		rk3x_i2c_clean_ipd(i2c); +		return; +	} + +	/* ack interrupt */ +	i2c_writel(i2c, REG_INT_START, REG_IPD); + +	/* disable start bit */ +	i2c_writel(i2c, i2c_readl(i2c, REG_CON) & ~REG_CON_START, REG_CON); + +	/* enable appropriate interrupts and transition */ +	if (i2c->mode == REG_CON_MOD_TX) { +		i2c_writel(i2c, REG_INT_MBTF | REG_INT_NAKRCV, REG_IEN); +		i2c->state = STATE_WRITE; +		rk3x_i2c_fill_transmit_buf(i2c); +	} else { +		/* in any other case, we are going to be reading. */ +		i2c_writel(i2c, REG_INT_MBRF | REG_INT_NAKRCV, REG_IEN); +		i2c->state = STATE_READ; +		rk3x_i2c_prepare_read(i2c); +	} +} + +static void rk3x_i2c_handle_write(struct rk3x_i2c *i2c, unsigned int ipd) +{ +	if (!(ipd & REG_INT_MBTF)) { +		rk3x_i2c_stop(i2c, -EIO); +		dev_err(i2c->dev, "unexpected irq in WRITE: 0x%x\n", ipd); +		rk3x_i2c_clean_ipd(i2c); +		return; +	} + +	/* ack interrupt */ +	i2c_writel(i2c, REG_INT_MBTF, REG_IPD); + +	/* are we finished? */ +	if (i2c->processed == i2c->msg->len) +		rk3x_i2c_stop(i2c, i2c->error); +	else +		rk3x_i2c_fill_transmit_buf(i2c); +} + +static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd) +{ +	unsigned int i; +	unsigned int len = i2c->msg->len - i2c->processed; +	u32 uninitialized_var(val); +	u8 byte; + +	/* we only care for MBRF here. */ +	if (!(ipd & REG_INT_MBRF)) +		return; + +	/* ack interrupt */ +	i2c_writel(i2c, REG_INT_MBRF, REG_IPD); + +	/* read the data from receive buffer */ +	for (i = 0; i < len; ++i) { +		if (i % 4 == 0) +			val = i2c_readl(i2c, RXBUFFER_BASE + (i / 4) * 4); + +		byte = (val >> ((i % 4) * 8)) & 0xff; +		i2c->msg->buf[i2c->processed++] = byte; +	} + +	/* are we finished? */ +	if (i2c->processed == i2c->msg->len) +		rk3x_i2c_stop(i2c, i2c->error); +	else +		rk3x_i2c_prepare_read(i2c); +} + +static void rk3x_i2c_handle_stop(struct rk3x_i2c *i2c, unsigned int ipd) +{ +	unsigned int con; + +	if (!(ipd & REG_INT_STOP)) { +		rk3x_i2c_stop(i2c, -EIO); +		dev_err(i2c->dev, "unexpected irq in STOP: 0x%x\n", ipd); +		rk3x_i2c_clean_ipd(i2c); +		return; +	} + +	/* ack interrupt */ +	i2c_writel(i2c, REG_INT_STOP, REG_IPD); + +	/* disable STOP bit */ +	con = i2c_readl(i2c, REG_CON); +	con &= ~REG_CON_STOP; +	i2c_writel(i2c, con, REG_CON); + +	i2c->busy = false; +	i2c->state = STATE_IDLE; + +	/* signal rk3x_i2c_xfer that we are finished */ +	wake_up(&i2c->wait); +} + +static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id) +{ +	struct rk3x_i2c *i2c = dev_id; +	unsigned int ipd; + +	spin_lock(&i2c->lock); + +	ipd = i2c_readl(i2c, REG_IPD); +	if (i2c->state == STATE_IDLE) { +		dev_warn(i2c->dev, "irq in STATE_IDLE, ipd = 0x%x\n", ipd); +		rk3x_i2c_clean_ipd(i2c); +		goto out; +	} + +	dev_dbg(i2c->dev, "IRQ: state %d, ipd: %x\n", i2c->state, ipd); + +	/* Clean interrupt bits we don't care about */ +	ipd &= ~(REG_INT_BRF | REG_INT_BTF); + +	if (ipd & REG_INT_NAKRCV) { +		/* +		 * We got a NACK in the last operation. Depending on whether +		 * IGNORE_NAK is set, we have to stop the operation and report +		 * an error. +		 */ +		i2c_writel(i2c, REG_INT_NAKRCV, REG_IPD); + +		ipd &= ~REG_INT_NAKRCV; + +		if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) +			rk3x_i2c_stop(i2c, -ENXIO); +	} + +	/* is there anything left to handle? */ +	if (unlikely(ipd == 0)) +		goto out; + +	switch (i2c->state) { +	case STATE_START: +		rk3x_i2c_handle_start(i2c, ipd); +		break; +	case STATE_WRITE: +		rk3x_i2c_handle_write(i2c, ipd); +		break; +	case STATE_READ: +		rk3x_i2c_handle_read(i2c, ipd); +		break; +	case STATE_STOP: +		rk3x_i2c_handle_stop(i2c, ipd); +		break; +	case STATE_IDLE: +		break; +	} + +out: +	spin_unlock(&i2c->lock); +	return IRQ_HANDLED; +} + +static void rk3x_i2c_set_scl_rate(struct rk3x_i2c *i2c, unsigned long scl_rate) +{ +	unsigned long i2c_rate = clk_get_rate(i2c->clk); +	unsigned int div; + +	/* SCL rate = (clk rate) / (8 * DIV) */ +	div = DIV_ROUND_UP(i2c_rate, scl_rate * 8); + +	/* The lower and upper half of the CLKDIV reg describe the length of +	 * SCL low & high periods. */ +	div = DIV_ROUND_UP(div, 2); + +	i2c_writel(i2c, (div << 16) | (div & 0xffff), REG_CLKDIV); +} + +/** + * Setup I2C registers for an I2C operation specified by msgs, num. + * + * Must be called with i2c->lock held. + * + * @msgs: I2C msgs to process + * @num: Number of msgs + * + * returns: Number of I2C msgs processed or negative in case of error + */ +static int rk3x_i2c_setup(struct rk3x_i2c *i2c, struct i2c_msg *msgs, int num) +{ +	u32 addr = (msgs[0].addr & 0x7f) << 1; +	int ret = 0; + +	/* +	 * The I2C adapter can issue a small (len < 4) write packet before +	 * reading. This speeds up SMBus-style register reads. +	 * The MRXADDR/MRXRADDR hold the slave address and the slave register +	 * address in this case. +	 */ + +	if (num >= 2 && msgs[0].len < 4 && +	    !(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD)) { +		u32 reg_addr = 0; +		int i; + +		dev_dbg(i2c->dev, "Combined write/read from addr 0x%x\n", +			addr >> 1); + +		/* Fill MRXRADDR with the register address(es) */ +		for (i = 0; i < msgs[0].len; ++i) { +			reg_addr |= msgs[0].buf[i] << (i * 8); +			reg_addr |= REG_MRXADDR_VALID(i); +		} + +		/* msgs[0] is handled by hw. */ +		i2c->msg = &msgs[1]; + +		i2c->mode = REG_CON_MOD_REGISTER_TX; + +		i2c_writel(i2c, addr | REG_MRXADDR_VALID(0), REG_MRXADDR); +		i2c_writel(i2c, reg_addr, REG_MRXRADDR); + +		ret = 2; +	} else { +		/* +		 * We'll have to do it the boring way and process the msgs +		 * one-by-one. +		 */ + +		if (msgs[0].flags & I2C_M_RD) { +			addr |= 1; /* set read bit */ + +			/* +			 * We have to transmit the slave addr first. Use +			 * MOD_REGISTER_TX for that purpose. +			 */ +			i2c->mode = REG_CON_MOD_REGISTER_TX; +			i2c_writel(i2c, addr | REG_MRXADDR_VALID(0), +				   REG_MRXADDR); +			i2c_writel(i2c, 0, REG_MRXRADDR); +		} else { +			i2c->mode = REG_CON_MOD_TX; +		} + +		i2c->msg = &msgs[0]; + +		ret = 1; +	} + +	i2c->addr = msgs[0].addr; +	i2c->busy = true; +	i2c->state = STATE_START; +	i2c->processed = 0; +	i2c->error = 0; + +	rk3x_i2c_clean_ipd(i2c); + +	return ret; +} + +static int rk3x_i2c_xfer(struct i2c_adapter *adap, +			 struct i2c_msg *msgs, int num) +{ +	struct rk3x_i2c *i2c = (struct rk3x_i2c *)adap->algo_data; +	unsigned long timeout, flags; +	int ret = 0; +	int i; + +	spin_lock_irqsave(&i2c->lock, flags); + +	clk_enable(i2c->clk); + +	/* The clock rate might have changed, so setup the divider again */ +	rk3x_i2c_set_scl_rate(i2c, i2c->scl_frequency); + +	i2c->is_last_msg = false; + +	/* +	 * Process msgs. We can handle more than one message at once (see +	 * rk3x_i2c_setup()). +	 */ +	for (i = 0; i < num; i += ret) { +		ret = rk3x_i2c_setup(i2c, msgs + i, num - i); + +		if (ret < 0) { +			dev_err(i2c->dev, "rk3x_i2c_setup() failed\n"); +			break; +		} + +		if (i + ret >= num) +			i2c->is_last_msg = true; + +		spin_unlock_irqrestore(&i2c->lock, flags); + +		rk3x_i2c_start(i2c); + +		timeout = wait_event_timeout(i2c->wait, !i2c->busy, +					     msecs_to_jiffies(WAIT_TIMEOUT)); + +		spin_lock_irqsave(&i2c->lock, flags); + +		if (timeout == 0) { +			dev_err(i2c->dev, "timeout, ipd: 0x%02x, state: %d\n", +				i2c_readl(i2c, REG_IPD), i2c->state); + +			/* Force a STOP condition without interrupt */ +			i2c_writel(i2c, 0, REG_IEN); +			i2c_writel(i2c, REG_CON_EN | REG_CON_STOP, REG_CON); + +			i2c->state = STATE_IDLE; + +			ret = -ETIMEDOUT; +			break; +		} + +		if (i2c->error) { +			ret = i2c->error; +			break; +		} +	} + +	clk_disable(i2c->clk); +	spin_unlock_irqrestore(&i2c->lock, flags); + +	return ret; +} + +static u32 rk3x_i2c_func(struct i2c_adapter *adap) +{ +	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING; +} + +static const struct i2c_algorithm rk3x_i2c_algorithm = { +	.master_xfer		= rk3x_i2c_xfer, +	.functionality		= rk3x_i2c_func, +}; + +static struct rk3x_i2c_soc_data soc_data[3] = { +	{ .grf_offset = 0x154 }, /* rk3066 */ +	{ .grf_offset = 0x0a4 }, /* rk3188 */ +	{ .grf_offset = -1 },    /* no I2C switching needed */ +}; + +static const struct of_device_id rk3x_i2c_match[] = { +	{ .compatible = "rockchip,rk3066-i2c", .data = (void *)&soc_data[0] }, +	{ .compatible = "rockchip,rk3188-i2c", .data = (void *)&soc_data[1] }, +	{ .compatible = "rockchip,rk3288-i2c", .data = (void *)&soc_data[2] }, +	{}, +}; + +static int rk3x_i2c_probe(struct platform_device *pdev) +{ +	struct device_node *np = pdev->dev.of_node; +	const struct of_device_id *match; +	struct rk3x_i2c *i2c; +	struct resource *mem; +	int ret = 0; +	int bus_nr; +	u32 value; +	int irq; + +	i2c = devm_kzalloc(&pdev->dev, sizeof(struct rk3x_i2c), GFP_KERNEL); +	if (!i2c) +		return -ENOMEM; + +	match = of_match_node(rk3x_i2c_match, np); +	i2c->soc_data = (struct rk3x_i2c_soc_data *)match->data; + +	if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", +				 &i2c->scl_frequency)) { +		dev_info(&pdev->dev, "using default SCL frequency: %d\n", +			 DEFAULT_SCL_RATE); +		i2c->scl_frequency = DEFAULT_SCL_RATE; +	} + +	if (i2c->scl_frequency == 0 || i2c->scl_frequency > 400 * 1000) { +		dev_warn(&pdev->dev, "invalid SCL frequency specified.\n"); +		dev_warn(&pdev->dev, "using default SCL frequency: %d\n", +			 DEFAULT_SCL_RATE); +		i2c->scl_frequency = DEFAULT_SCL_RATE; +	} + +	strlcpy(i2c->adap.name, "rk3x-i2c", sizeof(i2c->adap.name)); +	i2c->adap.owner = THIS_MODULE; +	i2c->adap.algo = &rk3x_i2c_algorithm; +	i2c->adap.retries = 3; +	i2c->adap.dev.of_node = np; +	i2c->adap.algo_data = i2c; +	i2c->adap.dev.parent = &pdev->dev; + +	i2c->dev = &pdev->dev; + +	spin_lock_init(&i2c->lock); +	init_waitqueue_head(&i2c->wait); + +	i2c->clk = devm_clk_get(&pdev->dev, NULL); +	if (IS_ERR(i2c->clk)) { +		dev_err(&pdev->dev, "cannot get clock\n"); +		return PTR_ERR(i2c->clk); +	} + +	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	i2c->regs = devm_ioremap_resource(&pdev->dev, mem); +	if (IS_ERR(i2c->regs)) +		return PTR_ERR(i2c->regs); + +	/* Try to set the I2C adapter number from dt */ +	bus_nr = of_alias_get_id(np, "i2c"); + +	/* +	 * Switch to new interface if the SoC also offers the old one. +	 * The control bit is located in the GRF register space. +	 */ +	if (i2c->soc_data->grf_offset >= 0) { +		struct regmap *grf; + +		grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); +		if (IS_ERR(grf)) { +			dev_err(&pdev->dev, +				"rk3x-i2c needs 'rockchip,grf' property\n"); +			return PTR_ERR(grf); +		} + +		if (bus_nr < 0) { +			dev_err(&pdev->dev, "rk3x-i2c needs i2cX alias"); +			return -EINVAL; +		} + +		/* 27+i: write mask, 11+i: value */ +		value = BIT(27 + bus_nr) | BIT(11 + bus_nr); + +		ret = regmap_write(grf, i2c->soc_data->grf_offset, value); +		if (ret != 0) { +			dev_err(i2c->dev, "Could not write to GRF: %d\n", ret); +			return ret; +		} +	} + +	/* IRQ setup */ +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) { +		dev_err(&pdev->dev, "cannot find rk3x IRQ\n"); +		return irq; +	} + +	ret = devm_request_irq(&pdev->dev, irq, rk3x_i2c_irq, +			       0, dev_name(&pdev->dev), i2c); +	if (ret < 0) { +		dev_err(&pdev->dev, "cannot request IRQ\n"); +		return ret; +	} + +	platform_set_drvdata(pdev, i2c); + +	ret = clk_prepare(i2c->clk); +	if (ret < 0) { +		dev_err(&pdev->dev, "Could not prepare clock\n"); +		return ret; +	} + +	ret = i2c_add_adapter(&i2c->adap); +	if (ret < 0) { +		dev_err(&pdev->dev, "Could not register adapter\n"); +		goto err_clk; +	} + +	dev_info(&pdev->dev, "Initialized RK3xxx I2C bus at %p\n", i2c->regs); + +	return 0; + +err_clk: +	clk_unprepare(i2c->clk); +	return ret; +} + +static int rk3x_i2c_remove(struct platform_device *pdev) +{ +	struct rk3x_i2c *i2c = platform_get_drvdata(pdev); + +	i2c_del_adapter(&i2c->adap); +	clk_unprepare(i2c->clk); + +	return 0; +} + +static struct platform_driver rk3x_i2c_driver = { +	.probe   = rk3x_i2c_probe, +	.remove  = rk3x_i2c_remove, +	.driver  = { +		.owner = THIS_MODULE, +		.name  = "rk3x-i2c", +		.of_match_table = rk3x_i2c_match, +	}, +}; + +module_platform_driver(rk3x_i2c_driver); + +MODULE_DESCRIPTION("Rockchip RK3xxx I2C Bus driver"); +MODULE_AUTHOR("Max Schwarz <max.schwarz@online.de>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/i2c/busses/i2c-robotfuzz-osif.c b/drivers/i2c/busses/i2c-robotfuzz-osif.c new file mode 100644 index 00000000000..ced9c6a308d --- /dev/null +++ b/drivers/i2c/busses/i2c-robotfuzz-osif.c @@ -0,0 +1,202 @@ +/* + * Driver for RobotFuzz OSIF + * + * Copyright (c) 2013 Andrew Lunn <andrew@lunn.ch> + * Copyright (c) 2007 Barry Carter <Barry.Carter@robotfuzz.com> + * + * Based on the i2c-tiny-usb by + * + * Copyright (C) 2006 Til Harbaum (Till@Harbaum.org) + * + *	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, version 2. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/i2c.h> +#include <linux/slab.h> +#include <linux/usb.h> + +#define OSIFI2C_READ		20 +#define OSIFI2C_WRITE		21 +#define OSIFI2C_STOP		22 +#define OSIFI2C_STATUS		23 +#define OSIFI2C_SET_BIT_RATE	24 + +#define STATUS_ADDRESS_ACK	0 +#define STATUS_ADDRESS_NAK	2 + +struct osif_priv { +	struct usb_device *usb_dev; +	struct usb_interface *interface; +	struct i2c_adapter adapter; +	unsigned char status; +}; + +static int osif_usb_read(struct i2c_adapter *adapter, int cmd, +			 int value, int index, void *data, int len) +{ +	struct osif_priv *priv = adapter->algo_data; + +	return usb_control_msg(priv->usb_dev, usb_rcvctrlpipe(priv->usb_dev, 0), +			       cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | +			       USB_DIR_IN, value, index, data, len, 2000); +} + +static int osif_usb_write(struct i2c_adapter *adapter, int cmd, +			  int value, int index, void *data, int len) +{ + +	struct osif_priv *priv = adapter->algo_data; + +	return usb_control_msg(priv->usb_dev, usb_sndctrlpipe(priv->usb_dev, 0), +			       cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE, +			       value, index, data, len, 2000); +} + +static int osif_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, +			 int num) +{ +	struct osif_priv *priv = adapter->algo_data; +	struct i2c_msg *pmsg; +	int ret = 0; +	int i, cmd; + +	for (i = 0; ret >= 0 && i < num; i++) { +		pmsg = &msgs[i]; + +		if (pmsg->flags & I2C_M_RD) { +			cmd = OSIFI2C_READ; + +			ret = osif_usb_read(adapter, cmd, pmsg->flags, +					    pmsg->addr, pmsg->buf, +					    pmsg->len); +			if (ret != pmsg->len) { +				dev_err(&adapter->dev, "failure reading data\n"); +				return -EREMOTEIO; +			} +		} else { +			cmd = OSIFI2C_WRITE; + +			ret = osif_usb_write(adapter, cmd, pmsg->flags, +					     pmsg->addr, pmsg->buf, pmsg->len); +			if (ret != pmsg->len) { +				dev_err(&adapter->dev, "failure writing data\n"); +				return -EREMOTEIO; +			} +		} + +		ret = osif_usb_read(adapter, OSIFI2C_STOP, 0, 0, NULL, 0); +		if (ret) { +			dev_err(&adapter->dev, "failure sending STOP\n"); +			return -EREMOTEIO; +		} + +		/* read status */ +		ret = osif_usb_read(adapter, OSIFI2C_STATUS, 0, 0, +				    &priv->status, 1); +		if (ret != 1) { +			dev_err(&adapter->dev, "failure reading status\n"); +			return -EREMOTEIO; +		} + +		if (priv->status != STATUS_ADDRESS_ACK) { +			dev_dbg(&adapter->dev, "status = %d\n", priv->status); +			return -EREMOTEIO; +		} +	} + +	return i; +} + +static u32 osif_func(struct i2c_adapter *adapter) +{ +	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static struct i2c_algorithm osif_algorithm = { +	.master_xfer	= osif_xfer, +	.functionality	= osif_func, +}; + +#define USB_OSIF_VENDOR_ID	0x1964 +#define USB_OSIF_PRODUCT_ID	0x0001 + +static struct usb_device_id osif_table[] = { +	{ USB_DEVICE(USB_OSIF_VENDOR_ID, USB_OSIF_PRODUCT_ID) }, +	{ } +}; +MODULE_DEVICE_TABLE(usb, osif_table); + +static int osif_probe(struct usb_interface *interface, +			     const struct usb_device_id *id) +{ +	int ret; +	struct osif_priv *priv; +	u16 version; + +	priv = devm_kzalloc(&interface->dev, sizeof(*priv), GFP_KERNEL); +	if (!priv) +		return -ENOMEM; + +	priv->usb_dev = usb_get_dev(interface_to_usbdev(interface)); +	priv->interface = interface; + +	usb_set_intfdata(interface, priv); + +	priv->adapter.owner = THIS_MODULE; +	priv->adapter.class = I2C_CLASS_HWMON; +	priv->adapter.algo = &osif_algorithm; +	priv->adapter.algo_data = priv; +	snprintf(priv->adapter.name, sizeof(priv->adapter.name), +		 "OSIF at bus %03d device %03d", +		 priv->usb_dev->bus->busnum, priv->usb_dev->devnum); + +	/* +	 * Set bus frequency. The frequency is: +	 * 120,000,000 / ( 16 + 2 * div * 4^prescale). +	 * Using dev = 52, prescale = 0 give 100KHz */ +	ret = osif_usb_read(&priv->adapter, OSIFI2C_SET_BIT_RATE, 52, 0, +			    NULL, 0); +	if (ret) { +		dev_err(&interface->dev, "failure sending bit rate"); +		usb_put_dev(priv->usb_dev); +		return ret; +	} + +	i2c_add_adapter(&(priv->adapter)); + +	version = le16_to_cpu(priv->usb_dev->descriptor.bcdDevice); +	dev_info(&interface->dev, +		 "version %x.%02x found at bus %03d address %03d", +		 version >> 8, version & 0xff, +		 priv->usb_dev->bus->busnum, priv->usb_dev->devnum); + +	return 0; +} + +static void osif_disconnect(struct usb_interface *interface) +{ +	struct osif_priv *priv = usb_get_intfdata(interface); + +	i2c_del_adapter(&(priv->adapter)); +	usb_set_intfdata(interface, NULL); +	usb_put_dev(priv->usb_dev); +} + +static struct usb_driver osif_driver = { +	.name		= "RobotFuzz Open Source InterFace, OSIF", +	.probe		= osif_probe, +	.disconnect	= osif_disconnect, +	.id_table	= osif_table, +}; + +module_usb_driver(osif_driver); + +MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>"); +MODULE_AUTHOR("Barry Carter <barry.carter@robotfuzz.com>"); +MODULE_DESCRIPTION("RobotFuzz OSIF driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 3747b9bf67d..e828a1dba0e 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -36,6 +36,7 @@  #include <linux/cpufreq.h>  #include <linux/slab.h>  #include <linux/io.h> +#include <linux/of.h>  #include <linux/of_gpio.h>  #include <linux/pinctrl/consumer.h> @@ -85,6 +86,7 @@  #define QUIRK_S3C2440		(1 << 0)  #define QUIRK_HDMIPHY		(1 << 1)  #define QUIRK_NO_GPIO		(1 << 2) +#define QUIRK_POLL		(1 << 3)  /* Max time to wait for bus to become idle after a xfer (in us) */  #define S3C2410_IDLE_TIMEOUT	5000 @@ -100,7 +102,7 @@ enum s3c24xx_i2c_state {  struct s3c24xx_i2c {  	wait_queue_head_t	wait; -	unsigned int            quirks; +	kernel_ulong_t		quirks;  	unsigned int		suspended:1;  	struct i2c_msg		*msg; @@ -122,7 +124,7 @@ struct s3c24xx_i2c {  	struct s3c2410_platform_i2c	*pdata;  	int			gpios[2];  	struct pinctrl          *pctrl; -#ifdef CONFIG_CPU_FREQ +#if defined(CONFIG_ARM_S3C24XX_CPUFREQ)  	struct notifier_block	freq_transition;  #endif  }; @@ -141,6 +143,8 @@ static struct platform_device_id s3c24xx_driver_ids[] = {  };  MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids); +static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat); +  #ifdef CONFIG_OF  static const struct of_device_id s3c24xx_i2c_match[] = {  	{ .compatible = "samsung,s3c2410-i2c", .data = (void *)0 }, @@ -149,6 +153,8 @@ static const struct of_device_id s3c24xx_i2c_match[] = {  	  .data = (void *)(QUIRK_S3C2440 | QUIRK_HDMIPHY | QUIRK_NO_GPIO) },  	{ .compatible = "samsung,exynos5440-i2c",  	  .data = (void *)(QUIRK_S3C2440 | QUIRK_NO_GPIO) }, +	{ .compatible = "samsung,exynos5-sata-phy-i2c", +	  .data = (void *)(QUIRK_S3C2440 | QUIRK_POLL | QUIRK_NO_GPIO) },  	{},  };  MODULE_DEVICE_TABLE(of, s3c24xx_i2c_match); @@ -159,12 +165,12 @@ MODULE_DEVICE_TABLE(of, s3c24xx_i2c_match);   * Get controller type either from device tree or platform device variant.  */ -static inline unsigned int s3c24xx_get_device_quirks(struct platform_device *pdev) +static inline kernel_ulong_t s3c24xx_get_device_quirks(struct platform_device *pdev)  {  	if (pdev->dev.of_node) {  		const struct of_device_id *match;  		match = of_match_node(s3c24xx_i2c_match, pdev->dev.of_node); -		return (unsigned int)match->data; +		return (kernel_ulong_t)match->data;  	}  	return platform_get_device_id(pdev)->driver_data; @@ -187,7 +193,8 @@ static inline void s3c24xx_i2c_master_complete(struct s3c24xx_i2c *i2c, int ret)  	if (ret)  		i2c->msg_idx = ret; -	wake_up(&i2c->wait); +	if (!(i2c->quirks & QUIRK_POLL)) +		wake_up(&i2c->wait);  }  static inline void s3c24xx_i2c_disable_ack(struct s3c24xx_i2c *i2c) @@ -224,6 +231,22 @@ static inline void s3c24xx_i2c_enable_irq(struct s3c24xx_i2c *i2c)  	writel(tmp | S3C2410_IICCON_IRQEN, i2c->regs + S3C2410_IICCON);  } +static bool is_ack(struct s3c24xx_i2c *i2c) +{ +	int tries; + +	for (tries = 50; tries; --tries) { +		if (readl(i2c->regs + S3C2410_IICCON) +			& S3C2410_IICCON_IRQPEND) { +			if (!(readl(i2c->regs + S3C2410_IICSTAT) +				& S3C2410_IICSTAT_LASTBIT)) +				return true; +		} +		usleep_range(1000, 2000); +	} +	dev_err(i2c->dev, "ack was not recieved\n"); +	return false; +}  /* s3c24xx_i2c_message_start   * @@ -268,6 +291,16 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,  	stat |= S3C2410_IICSTAT_START;  	writel(stat, i2c->regs + S3C2410_IICSTAT); + +	if (i2c->quirks & QUIRK_POLL) { +		while ((i2c->msg_num != 0) && is_ack(i2c)) { +			i2c_s3c_irq_nextbyte(i2c, stat); +			stat = readl(i2c->regs + S3C2410_IICSTAT); + +			if (stat & S3C2410_IICSTAT_ARBITR) +				dev_err(i2c->dev, "deal with arbitration loss\n"); +		} +	}  }  static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret) @@ -568,6 +601,31 @@ static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id)  	return IRQ_HANDLED;  } +/* + * Disable the bus so that we won't get any interrupts from now on, or try + * to drive any lines. This is the default state when we don't have + * anything to send/receive. + * + * If there is an event on the bus, or we have a pre-existing event at + * kernel boot time, we may not notice the event and the I2C controller + * will lock the bus with the I2C clock line low indefinitely. + */ +static inline void s3c24xx_i2c_disable_bus(struct s3c24xx_i2c *i2c) +{ +	unsigned long tmp; + +	/* Stop driving the I2C pins */ +	tmp = readl(i2c->regs + S3C2410_IICSTAT); +	tmp &= ~S3C2410_IICSTAT_TXRXEN; +	writel(tmp, i2c->regs + S3C2410_IICSTAT); + +	/* We don't expect any interrupts now, and don't want send acks */ +	tmp = readl(i2c->regs + S3C2410_IICCON); +	tmp &= ~(S3C2410_IICCON_IRQEN | S3C2410_IICCON_IRQPEND | +		S3C2410_IICCON_ACKEN); +	writel(tmp, i2c->regs + S3C2410_IICCON); +} +  /* s3c24xx_i2c_set_master   * @@ -675,6 +733,15 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,  	s3c24xx_i2c_enable_irq(i2c);  	s3c24xx_i2c_message_start(i2c, msgs); +	if (i2c->quirks & QUIRK_POLL) { +		ret = i2c->msg_idx; + +		if (ret != num) +			dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret); + +		goto out; +	} +  	timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);  	ret = i2c->msg_idx; @@ -693,7 +760,11 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,  	s3c24xx_i2c_wait_idle(i2c); +	s3c24xx_i2c_disable_bus(i2c); +   out: +	i2c->state = STATE_IDLE; +  	return ret;  } @@ -820,6 +891,9 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)  	if (div1 == 512)  		iiccon |= S3C2410_IICCON_TXDIV_512; +	if (i2c->quirks & QUIRK_POLL) +		iiccon |= S3C2410_IICCON_SCALE(2); +  	writel(iiccon, i2c->regs + S3C2410_IICCON);  	if (i2c->quirks & QUIRK_S3C2440) { @@ -842,7 +916,7 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)  	return 0;  } -#ifdef CONFIG_CPU_FREQ +#if defined(CONFIG_ARM_S3C24XX_CPUFREQ)  #define freq_to_i2c(_n) container_of(_n, struct s3c24xx_i2c, freq_transition) @@ -959,7 +1033,6 @@ static void s3c24xx_i2c_dt_gpio_free(struct s3c24xx_i2c *i2c)  static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)  { -	unsigned long iicon = S3C2410_IICCON_IRQEN | S3C2410_IICCON_ACKEN;  	struct s3c2410_platform_i2c *pdata;  	unsigned int freq; @@ -973,12 +1046,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)  	dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr); -	writel(iicon, i2c->regs + S3C2410_IICCON); +	writel(0, i2c->regs + S3C2410_IICCON); +	writel(0, i2c->regs + S3C2410_IICSTAT);  	/* we need to work out the divisors for the clock... */  	if (s3c24xx_i2c_clockrate(i2c, &freq) != 0) { -		writel(0, i2c->regs + S3C2410_IICCON);  		dev_err(i2c->dev, "cannot meet bus frequency required\n");  		return -EINVAL;  	} @@ -986,7 +1059,8 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)  	/* todo - check that the i2c lines aren't being dragged anywhere */  	dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq); -	dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon); +	dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02x\n", +		readl(i2c->regs + S3C2410_IICCON));  	return 0;  } @@ -1040,16 +1114,12 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)  	}  	i2c = devm_kzalloc(&pdev->dev, sizeof(struct s3c24xx_i2c), GFP_KERNEL); -	if (!i2c) { -		dev_err(&pdev->dev, "no memory for state\n"); +	if (!i2c)  		return -ENOMEM; -	}  	i2c->pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); -	if (!i2c->pdata) { -		dev_err(&pdev->dev, "no memory for platform data\n"); +	if (!i2c->pdata)  		return -ENOMEM; -	}  	i2c->quirks = s3c24xx_get_device_quirks(pdev);  	if (pdata) @@ -1061,7 +1131,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)  	i2c->adap.owner   = THIS_MODULE;  	i2c->adap.algo    = &s3c24xx_i2c_algorithm;  	i2c->adap.retries = 2; -	i2c->adap.class   = I2C_CLASS_HWMON | I2C_CLASS_SPD; +	i2c->adap.class   = I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED;  	i2c->tx_setup     = 50;  	init_waitqueue_head(&i2c->wait); @@ -1117,18 +1187,20 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)  	 * ensure no current IRQs pending  	 */ -	i2c->irq = ret = platform_get_irq(pdev, 0); -	if (ret <= 0) { -		dev_err(&pdev->dev, "cannot find IRQ\n"); -		return ret; -	} +	if (!(i2c->quirks & QUIRK_POLL)) { +		i2c->irq = ret = platform_get_irq(pdev, 0); +		if (ret <= 0) { +			dev_err(&pdev->dev, "cannot find IRQ\n"); +			return ret; +		}  	ret = devm_request_irq(&pdev->dev, i2c->irq, s3c24xx_i2c_irq, 0, -			       dev_name(&pdev->dev), i2c); +				dev_name(&pdev->dev), i2c); -	if (ret != 0) { -		dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq); -		return ret; +		if (ret != 0) { +			dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq); +			return ret; +		}  	}  	ret = s3c24xx_i2c_register_cpufreq(i2c); @@ -1200,10 +1272,10 @@ static int s3c24xx_i2c_resume(struct device *dev)  	struct platform_device *pdev = to_platform_device(dev);  	struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); -	i2c->suspended = 0;  	clk_prepare_enable(i2c->clk);  	s3c24xx_i2c_init(i2c);  	clk_disable_unprepare(i2c->clk); +	i2c->suspended = 0;  	return 0;  } diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c index c447e8d40b7..dfc98df7b1b 100644 --- a/drivers/i2c/busses/i2c-scmi.c +++ b/drivers/i2c/busses/i2c-scmi.c @@ -12,7 +12,6 @@  #include <linux/slab.h>  #include <linux/kernel.h>  #include <linux/stddef.h> -#include <linux/init.h>  #include <linux/i2c.h>  #include <linux/acpi.h> @@ -223,7 +222,7 @@ acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,  		goto out;  	obj = pkg->package.elements + 1; -	if (obj == NULL || obj->type != ACPI_TYPE_INTEGER) { +	if (obj->type != ACPI_TYPE_INTEGER) {  		ACPI_ERROR((AE_INFO, "Invalid argument type"));  		result = -EIO;  		goto out; @@ -235,7 +234,7 @@ acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,  	case I2C_SMBUS_BYTE:  	case I2C_SMBUS_BYTE_DATA:  	case I2C_SMBUS_WORD_DATA: -		if (obj == NULL || obj->type != ACPI_TYPE_INTEGER) { +		if (obj->type != ACPI_TYPE_INTEGER) {  			ACPI_ERROR((AE_INFO, "Invalid argument type"));  			result = -EIO;  			goto out; @@ -246,7 +245,7 @@ acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,  			data->byte = obj->integer.value;  		break;  	case I2C_SMBUS_BLOCK_DATA: -		if (obj == NULL || obj->type != ACPI_TYPE_BUFFER) { +		if (obj->type != ACPI_TYPE_BUFFER) {  			ACPI_ERROR((AE_INFO, "Invalid argument type"));  			result = -EIO;  			goto out; diff --git a/drivers/i2c/busses/i2c-sh7760.c b/drivers/i2c/busses/i2c-sh7760.c index 5e8f136e233..d76f3d9737e 100644 --- a/drivers/i2c/busses/i2c-sh7760.c +++ b/drivers/i2c/busses/i2c-sh7760.c @@ -11,7 +11,6 @@  #include <linux/delay.h>  #include <linux/err.h>  #include <linux/i2c.h> -#include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/ioport.h>  #include <linux/platform_device.h> diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 55110ddbed1..8b5e79cb446 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -32,6 +32,7 @@  #include <linux/clk.h>  #include <linux/io.h>  #include <linux/slab.h> +#include <linux/of_device.h>  #include <linux/i2c/i2c-sh_mobile.h>  /* Transmit operation:                                                      */ @@ -139,6 +140,10 @@ struct sh_mobile_i2c_data {  	bool send_stop;  }; +struct sh_mobile_dt_config { +	int clks_per_count; +}; +  #define IIC_FLAG_HAS_ICIC67	(1 << 0)  #define STANDARD_MODE		100000 @@ -194,7 +199,7 @@ static void iic_set_clr(struct sh_mobile_i2c_data *pd, int offs,  	iic_wr(pd, offs, (iic_rd(pd, offs) | set) & ~clr);  } -static u32 sh_mobile_i2c_iccl(unsigned long count_khz, u32 tLOW, u32 tf, int offset) +static u32 sh_mobile_i2c_iccl(unsigned long count_khz, u32 tLOW, u32 tf)  {  	/*  	 * Conditional expression: @@ -206,10 +211,10 @@ static u32 sh_mobile_i2c_iccl(unsigned long count_khz, u32 tLOW, u32 tf, int off  	 * account the fall time of SCL signal (tf).  Default tf value  	 * should be 0.3 us, for safety.  	 */ -	return (((count_khz * (tLOW + tf)) + 5000) / 10000) + offset; +	return (((count_khz * (tLOW + tf)) + 5000) / 10000);  } -static u32 sh_mobile_i2c_icch(unsigned long count_khz, u32 tHIGH, u32 tf, int offset) +static u32 sh_mobile_i2c_icch(unsigned long count_khz, u32 tHIGH, u32 tf)  {  	/*  	 * Conditional expression: @@ -225,59 +230,65 @@ static u32 sh_mobile_i2c_icch(unsigned long count_khz, u32 tHIGH, u32 tf, int of  	 * to take into account the fall time of SDA signal (tf) at START  	 * condition, in order to meet both tHIGH and tHD;STA specs.  	 */ -	return (((count_khz * (tHIGH + tf)) + 5000) / 10000) + offset; +	return (((count_khz * (tHIGH + tf)) + 5000) / 10000);  } -static void sh_mobile_i2c_init(struct sh_mobile_i2c_data *pd) +static int sh_mobile_i2c_init(struct sh_mobile_i2c_data *pd)  {  	unsigned long i2c_clk_khz;  	u32 tHIGH, tLOW, tf; -	int offset; +	uint16_t max_val;  	/* Get clock rate after clock is enabled */ -	clk_enable(pd->clk); +	clk_prepare_enable(pd->clk);  	i2c_clk_khz = clk_get_rate(pd->clk) / 1000; +	clk_disable_unprepare(pd->clk);  	i2c_clk_khz /= pd->clks_per_count;  	if (pd->bus_speed == STANDARD_MODE) {  		tLOW	= 47;	/* tLOW = 4.7 us */  		tHIGH	= 40;	/* tHD;STA = tHIGH = 4.0 us */  		tf	= 3;	/* tf = 0.3 us */ -		offset	= 0;	/* No offset */  	} else if (pd->bus_speed == FAST_MODE) {  		tLOW	= 13;	/* tLOW = 1.3 us */  		tHIGH	= 6;	/* tHD;STA = tHIGH = 0.6 us */  		tf	= 3;	/* tf = 0.3 us */ -		offset	= 0;	/* No offset */  	} else {  		dev_err(pd->dev, "unrecognized bus speed %lu Hz\n",  			pd->bus_speed); -		goto out; +		return -EINVAL; +	} + +	pd->iccl = sh_mobile_i2c_iccl(i2c_clk_khz, tLOW, tf); +	pd->icch = sh_mobile_i2c_icch(i2c_clk_khz, tHIGH, tf); + +	max_val = pd->flags & IIC_FLAG_HAS_ICIC67 ? 0x1ff : 0xff; +	if (pd->iccl > max_val || pd->icch > max_val) { +		dev_err(pd->dev, "timing values out of range: L/H=0x%x/0x%x\n", +			pd->iccl, pd->icch); +		return -EINVAL;  	} -	pd->iccl = sh_mobile_i2c_iccl(i2c_clk_khz, tLOW, tf, offset);  	/* one more bit of ICCL in ICIC */ -	if ((pd->iccl > 0xff) && (pd->flags & IIC_FLAG_HAS_ICIC67)) +	if (pd->iccl & 0x100)  		pd->icic |= ICIC_ICCLB8;  	else  		pd->icic &= ~ICIC_ICCLB8; -	pd->icch = sh_mobile_i2c_icch(i2c_clk_khz, tHIGH, tf, offset);  	/* one more bit of ICCH in ICIC */ -	if ((pd->icch > 0xff) && (pd->flags & IIC_FLAG_HAS_ICIC67)) +	if (pd->icch & 0x100)  		pd->icic |= ICIC_ICCHB8;  	else  		pd->icic &= ~ICIC_ICCHB8; -out: -	clk_disable(pd->clk); +	return 0;  }  static void activate_ch(struct sh_mobile_i2c_data *pd)  {  	/* Wake up device and enable clock */  	pm_runtime_get_sync(pd->dev); -	clk_enable(pd->clk); +	clk_prepare_enable(pd->clk);  	/* Enable channel and configure rx ack */  	iic_set_clr(pd, ICCR, ICCR_ICE, 0); @@ -300,7 +311,7 @@ static void deactivate_ch(struct sh_mobile_i2c_data *pd)  	iic_set_clr(pd, ICCR, 0, ICCR_ICE);  	/* Disable clock and mark device as idle */ -	clk_disable(pd->clk); +	clk_disable_unprepare(pd->clk);  	pm_runtime_put_sync(pd->dev);  } @@ -316,7 +327,7 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,  	switch (op) {  	case OP_START: /* issue start and trigger DTE interrupt */ -		iic_wr(pd, ICCR, 0x94); +		iic_wr(pd, ICCR, ICCR_ICE | ICCR_TRS | ICCR_BBSY);  		break;  	case OP_TX_FIRST: /* disable DTE interrupt and write data */  		iic_wr(pd, ICIC, ICIC_WAITE | ICIC_ALE | ICIC_TACKE); @@ -327,10 +338,11 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,  		break;  	case OP_TX_STOP: /* write data and issue a stop afterwards */  		iic_wr(pd, ICDR, data); -		iic_wr(pd, ICCR, pd->send_stop ? 0x90 : 0x94); +		iic_wr(pd, ICCR, pd->send_stop ? ICCR_ICE | ICCR_TRS +					       : ICCR_ICE | ICCR_TRS | ICCR_BBSY);  		break;  	case OP_TX_TO_RX: /* select read mode */ -		iic_wr(pd, ICCR, 0x81); +		iic_wr(pd, ICCR, ICCR_ICE | ICCR_SCP);  		break;  	case OP_RX: /* just read data */  		ret = iic_rd(pd, ICDR); @@ -338,13 +350,13 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,  	case OP_RX_STOP: /* enable DTE interrupt, issue stop */  		iic_wr(pd, ICIC,  		       ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); -		iic_wr(pd, ICCR, 0xc0); +		iic_wr(pd, ICCR, ICCR_ICE | ICCR_RACK);  		break;  	case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */  		iic_wr(pd, ICIC,  		       ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);  		ret = iic_rd(pd, ICDR); -		iic_wr(pd, ICCR, 0xc0); +		iic_wr(pd, ICCR, ICCR_ICE | ICCR_RACK);  		break;  	} @@ -479,7 +491,7 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg,  {  	if (usr_msg->len == 0 && (usr_msg->flags & I2C_M_RD)) {  		dev_err(pd->dev, "Unsupported zero length i2c read\n"); -		return -EIO; +		return -EOPNOTSUPP;  	}  	if (do_init) { @@ -514,17 +526,12 @@ static int poll_dte(struct sh_mobile_i2c_data *pd)  			break;  		if (val & ICSR_TACK) -			return -EIO; +			return -ENXIO;  		udelay(10);  	} -	if (!i) { -		dev_warn(pd->dev, "Timeout polling for DTE!\n"); -		return -ETIMEDOUT; -	} - -	return 0; +	return i ? 0 : -ETIMEDOUT;  }  static int poll_busy(struct sh_mobile_i2c_data *pd) @@ -542,20 +549,18 @@ static int poll_busy(struct sh_mobile_i2c_data *pd)  		 */  		if (!(val & ICSR_BUSY)) {  			/* handle missing acknowledge and arbitration lost */ -			if ((val | pd->sr) & (ICSR_TACK | ICSR_AL)) -				return -EIO; +			val |= pd->sr; +			if (val & ICSR_TACK) +				return -ENXIO; +			if (val & ICSR_AL) +				return -EAGAIN;  			break;  		}  		udelay(10);  	} -	if (!i) { -		dev_err(pd->dev, "Polling timed out\n"); -		return -ETIMEDOUT; -	} - -	return 0; +	return i ? 0 : -ETIMEDOUT;  }  static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, @@ -617,42 +622,44 @@ static struct i2c_algorithm sh_mobile_i2c_algorithm = {  	.master_xfer	= sh_mobile_i2c_xfer,  }; -static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook) +static const struct sh_mobile_dt_config default_dt_config = { +	.clks_per_count = 1, +}; + +static const struct sh_mobile_dt_config rcar_gen2_dt_config = { +	.clks_per_count = 2, +}; + +static const struct of_device_id sh_mobile_i2c_dt_ids[] = { +	{ .compatible = "renesas,rmobile-iic", .data = &default_dt_config }, +	{ .compatible = "renesas,iic-r8a7790", .data = &rcar_gen2_dt_config }, +	{ .compatible = "renesas,iic-r8a7791", .data = &rcar_gen2_dt_config }, +	{ .compatible = "renesas,iic-r8a7792", .data = &rcar_gen2_dt_config }, +	{ .compatible = "renesas,iic-r8a7793", .data = &rcar_gen2_dt_config }, +	{ .compatible = "renesas,iic-r8a7794", .data = &rcar_gen2_dt_config }, +	{}, +}; +MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids); + +static int sh_mobile_i2c_hook_irqs(struct platform_device *dev)  {  	struct resource *res; -	int ret = -ENXIO; -	int n, k = 0; +	resource_size_t n; +	int k = 0, ret;  	while ((res = platform_get_resource(dev, IORESOURCE_IRQ, k))) { -		for (n = res->start; hook && n <= res->end; n++) { -			if (request_irq(n, sh_mobile_i2c_isr, 0, -					dev_name(&dev->dev), dev)) { -				for (n--; n >= res->start; n--) -					free_irq(n, dev); - -				goto rollback; +		for (n = res->start; n <= res->end; n++) { +			ret = devm_request_irq(&dev->dev, n, sh_mobile_i2c_isr, +					  0, dev_name(&dev->dev), dev); +			if (ret) { +				dev_err(&dev->dev, "cannot request IRQ %pa\n", &n); +				return ret;  			}  		}  		k++;  	} -	if (hook) -		return k > 0 ? 0 : -ENOENT; - -	ret = 0; - - rollback: -	k--; - -	while (k >= 0) { -		res = platform_get_resource(dev, IORESOURCE_IRQ, k); -		for (n = res->start; n <= res->end; n++) -			free_irq(n, dev); - -		k--; -	} - -	return ret; +	return k > 0 ? 0 : -ENOENT;  }  static int sh_mobile_i2c_probe(struct platform_device *dev) @@ -661,62 +668,64 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)  	struct sh_mobile_i2c_data *pd;  	struct i2c_adapter *adap;  	struct resource *res; -	int size;  	int ret; +	u32 bus_speed; -	pd = kzalloc(sizeof(struct sh_mobile_i2c_data), GFP_KERNEL); -	if (pd == NULL) { -		dev_err(&dev->dev, "cannot allocate private data\n"); +	pd = devm_kzalloc(&dev->dev, sizeof(struct sh_mobile_i2c_data), GFP_KERNEL); +	if (!pd)  		return -ENOMEM; -	} -	pd->clk = clk_get(&dev->dev, NULL); +	pd->clk = devm_clk_get(&dev->dev, NULL);  	if (IS_ERR(pd->clk)) {  		dev_err(&dev->dev, "cannot get clock\n"); -		ret = PTR_ERR(pd->clk); -		goto err; +		return PTR_ERR(pd->clk);  	} -	ret = sh_mobile_i2c_hook_irqs(dev, 1); -	if (ret) { -		dev_err(&dev->dev, "cannot request IRQ\n"); -		goto err_clk; -	} +	ret = sh_mobile_i2c_hook_irqs(dev); +	if (ret) +		return ret;  	pd->dev = &dev->dev;  	platform_set_drvdata(dev, pd);  	res = platform_get_resource(dev, IORESOURCE_MEM, 0); -	if (res == NULL) { -		dev_err(&dev->dev, "cannot find IO resource\n"); -		ret = -ENOENT; -		goto err_irq; -	} - -	size = resource_size(res); -	pd->reg = ioremap(res->start, size); -	if (pd->reg == NULL) { -		dev_err(&dev->dev, "cannot map IO\n"); -		ret = -ENXIO; -		goto err_irq; -	} +	pd->reg = devm_ioremap_resource(&dev->dev, res); +	if (IS_ERR(pd->reg)) +		return PTR_ERR(pd->reg);  	/* Use platform data bus speed or STANDARD_MODE */ -	pd->bus_speed = STANDARD_MODE; -	if (pdata && pdata->bus_speed) -		pd->bus_speed = pdata->bus_speed; +	ret = of_property_read_u32(dev->dev.of_node, "clock-frequency", &bus_speed); +	pd->bus_speed = ret ? STANDARD_MODE : bus_speed; +  	pd->clks_per_count = 1; -	if (pdata && pdata->clks_per_count) -		pd->clks_per_count = pdata->clks_per_count; + +	if (dev->dev.of_node) { +		const struct of_device_id *match; + +		match = of_match_device(sh_mobile_i2c_dt_ids, &dev->dev); +		if (match) { +			const struct sh_mobile_dt_config *config; + +			config = match->data; +			pd->clks_per_count = config->clks_per_count; +		} +	} else { +		if (pdata && pdata->bus_speed) +			pd->bus_speed = pdata->bus_speed; +		if (pdata && pdata->clks_per_count) +			pd->clks_per_count = pdata->clks_per_count; +	}  	/* The IIC blocks on SH-Mobile ARM processors  	 * come with two new bits in ICIC.  	 */ -	if (size > 0x17) +	if (resource_size(res) > 0x17)  		pd->flags |= IIC_FLAG_HAS_ICIC67; -	sh_mobile_i2c_init(pd); +	ret = sh_mobile_i2c_init(pd); +	if (ret) +		return ret;  	/* Enable Runtime PM for this device.  	 * @@ -750,24 +759,14 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)  	ret = i2c_add_numbered_adapter(adap);  	if (ret < 0) {  		dev_err(&dev->dev, "cannot add numbered adapter\n"); -		goto err_all; +		return ret;  	}  	dev_info(&dev->dev, -		 "I2C adapter %d with bus speed %lu Hz (L/H=%x/%x)\n", +		 "I2C adapter %d with bus speed %lu Hz (L/H=0x%x/0x%x)\n",  		 adap->nr, pd->bus_speed, pd->iccl, pd->icch);  	return 0; - - err_all: -	iounmap(pd->reg); - err_irq: -	sh_mobile_i2c_hook_irqs(dev, 0); - err_clk: -	clk_put(pd->clk); - err: -	kfree(pd); -	return ret;  }  static int sh_mobile_i2c_remove(struct platform_device *dev) @@ -775,11 +774,7 @@ static int sh_mobile_i2c_remove(struct platform_device *dev)  	struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);  	i2c_del_adapter(&pd->adap); -	iounmap(pd->reg); -	sh_mobile_i2c_hook_irqs(dev, 0); -	clk_put(pd->clk);  	pm_runtime_disable(&dev->dev); -	kfree(pd);  	return 0;  } @@ -800,12 +795,6 @@ static const struct dev_pm_ops sh_mobile_i2c_dev_pm_ops = {  	.runtime_resume = sh_mobile_i2c_runtime_nop,  }; -static const struct of_device_id sh_mobile_i2c_dt_ids[] = { -	{ .compatible = "renesas,rmobile-iic", }, -	{}, -}; -MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids); -  static struct platform_driver sh_mobile_i2c_driver = {  	.driver		= {  		.name		= "i2c-sh_mobile", diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c index 4fc87e7c94c..964e5c6f84a 100644 --- a/drivers/i2c/busses/i2c-simtec.c +++ b/drivers/i2c/busses/i2c-simtec.c @@ -20,7 +20,6 @@  #include <linux/kernel.h>  #include <linux/module.h> -#include <linux/init.h>  #include <linux/delay.h>  #include <linux/platform_device.h>  #include <linux/slab.h> @@ -78,10 +77,8 @@ static int simtec_i2c_probe(struct platform_device *dev)  	int ret;  	pd = kzalloc(sizeof(struct simtec_i2c_data), GFP_KERNEL); -	if (pd == NULL) { -		dev_err(&dev->dev, "cannot allocate private data\n"); +	if (pd == NULL)  		return -ENOMEM; -	}  	platform_set_drvdata(dev, pd); diff --git a/drivers/i2c/busses/i2c-sirf.c b/drivers/i2c/busses/i2c-sirf.c index 6784f7f527a..a3216defc1d 100644 --- a/drivers/i2c/busses/i2c-sirf.c +++ b/drivers/i2c/busses/i2c-sirf.c @@ -307,12 +307,11 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)  	siic = devm_kzalloc(&pdev->dev, sizeof(*siic), GFP_KERNEL);  	if (!siic) { -		dev_err(&pdev->dev, "Can't allocate driver data\n");  		err = -ENOMEM;  		goto out;  	}  	adap = &siic->adapter; -	adap->class = I2C_CLASS_HWMON; +	adap->class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED;  	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	siic->base = devm_ioremap_resource(&pdev->dev, mem_res); diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c index 79fd96a0438..ac9bc33acef 100644 --- a/drivers/i2c/busses/i2c-sis5595.c +++ b/drivers/i2c/busses/i2c-sis5595.c @@ -369,7 +369,7 @@ static struct i2c_adapter sis5595_adapter = {  	.algo		= &smbus_algorithm,  }; -static DEFINE_PCI_DEVICE_TABLE(sis5595_ids) = { +static const struct pci_device_id sis5595_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },   	{ 0, }  }; diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index 36a9556d7cf..c6366733008 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -45,7 +45,6 @@  #include <linux/delay.h>  #include <linux/pci.h>  #include <linux/ioport.h> -#include <linux/init.h>  #include <linux/i2c.h>  #include <linux/acpi.h>  #include <linux/io.h> @@ -511,7 +510,7 @@ static struct i2c_adapter sis630_adapter = {  	.retries	= 3  }; -static DEFINE_PCI_DEVICE_TABLE(sis630_ids) = { +static const struct pci_device_id sis630_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },  	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },  	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_964) }, diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index b9faf9b6002..8dc2fc5f74f 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c @@ -36,7 +36,6 @@  #include <linux/stddef.h>  #include <linux/ioport.h>  #include <linux/i2c.h> -#include <linux/init.h>  #include <linux/acpi.h>  #include <linux/io.h> @@ -245,7 +244,7 @@ static struct i2c_adapter sis96x_adapter = {  	.algo		= &smbus_algorithm,  }; -static DEFINE_PCI_DEVICE_TABLE(sis96x_ids) = { +static const struct pci_device_id sis96x_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },  	{ 0, }  }; diff --git a/drivers/i2c/busses/i2c-st.c b/drivers/i2c/busses/i2c-st.c new file mode 100644 index 00000000000..95b94767038 --- /dev/null +++ b/drivers/i2c/busses/i2c-st.c @@ -0,0 +1,872 @@ +/* + * Copyright (C) 2013 STMicroelectronics + * + * I2C master mode controller driver, used in STMicroelectronics devices. + * + * Author: Maxime Coquelin <maxime.coquelin@st.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/err.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> + +/* SSC registers */ +#define SSC_BRG				0x000 +#define SSC_TBUF			0x004 +#define SSC_RBUF			0x008 +#define SSC_CTL				0x00C +#define SSC_IEN				0x010 +#define SSC_STA				0x014 +#define SSC_I2C				0x018 +#define SSC_SLAD			0x01C +#define SSC_REP_START_HOLD		0x020 +#define SSC_START_HOLD			0x024 +#define SSC_REP_START_SETUP		0x028 +#define SSC_DATA_SETUP			0x02C +#define SSC_STOP_SETUP			0x030 +#define SSC_BUS_FREE			0x034 +#define SSC_TX_FSTAT			0x038 +#define SSC_RX_FSTAT			0x03C +#define SSC_PRE_SCALER_BRG		0x040 +#define SSC_CLR				0x080 +#define SSC_NOISE_SUPP_WIDTH		0x100 +#define SSC_PRSCALER			0x104 +#define SSC_NOISE_SUPP_WIDTH_DATAOUT	0x108 +#define SSC_PRSCALER_DATAOUT		0x10c + +/* SSC Control */ +#define SSC_CTL_DATA_WIDTH_9		0x8 +#define SSC_CTL_DATA_WIDTH_MSK		0xf +#define SSC_CTL_BM			0xf +#define SSC_CTL_HB			BIT(4) +#define SSC_CTL_PH			BIT(5) +#define SSC_CTL_PO			BIT(6) +#define SSC_CTL_SR			BIT(7) +#define SSC_CTL_MS			BIT(8) +#define SSC_CTL_EN			BIT(9) +#define SSC_CTL_LPB			BIT(10) +#define SSC_CTL_EN_TX_FIFO		BIT(11) +#define SSC_CTL_EN_RX_FIFO		BIT(12) +#define SSC_CTL_EN_CLST_RX		BIT(13) + +/* SSC Interrupt Enable */ +#define SSC_IEN_RIEN			BIT(0) +#define SSC_IEN_TIEN			BIT(1) +#define SSC_IEN_TEEN			BIT(2) +#define SSC_IEN_REEN			BIT(3) +#define SSC_IEN_PEEN			BIT(4) +#define SSC_IEN_AASEN			BIT(6) +#define SSC_IEN_STOPEN			BIT(7) +#define SSC_IEN_ARBLEN			BIT(8) +#define SSC_IEN_NACKEN			BIT(10) +#define SSC_IEN_REPSTRTEN		BIT(11) +#define SSC_IEN_TX_FIFO_HALF		BIT(12) +#define SSC_IEN_RX_FIFO_HALF_FULL	BIT(14) + +/* SSC Status */ +#define SSC_STA_RIR			BIT(0) +#define SSC_STA_TIR			BIT(1) +#define SSC_STA_TE			BIT(2) +#define SSC_STA_RE			BIT(3) +#define SSC_STA_PE			BIT(4) +#define SSC_STA_CLST			BIT(5) +#define SSC_STA_AAS			BIT(6) +#define SSC_STA_STOP			BIT(7) +#define SSC_STA_ARBL			BIT(8) +#define SSC_STA_BUSY			BIT(9) +#define SSC_STA_NACK			BIT(10) +#define SSC_STA_REPSTRT			BIT(11) +#define SSC_STA_TX_FIFO_HALF		BIT(12) +#define SSC_STA_TX_FIFO_FULL		BIT(13) +#define SSC_STA_RX_FIFO_HALF		BIT(14) + +/* SSC I2C Control */ +#define SSC_I2C_I2CM			BIT(0) +#define SSC_I2C_STRTG			BIT(1) +#define SSC_I2C_STOPG			BIT(2) +#define SSC_I2C_ACKG			BIT(3) +#define SSC_I2C_AD10			BIT(4) +#define SSC_I2C_TXENB			BIT(5) +#define SSC_I2C_REPSTRTG		BIT(11) +#define SSC_I2C_SLAVE_DISABLE		BIT(12) + +/* SSC Tx FIFO Status */ +#define SSC_TX_FSTAT_STATUS		0x07 + +/* SSC Rx FIFO Status */ +#define SSC_RX_FSTAT_STATUS		0x07 + +/* SSC Clear bit operation */ +#define SSC_CLR_SSCAAS			BIT(6) +#define SSC_CLR_SSCSTOP			BIT(7) +#define SSC_CLR_SSCARBL			BIT(8) +#define SSC_CLR_NACK			BIT(10) +#define SSC_CLR_REPSTRT			BIT(11) + +/* SSC Clock Prescaler */ +#define SSC_PRSC_VALUE			0x0f + + +#define SSC_TXFIFO_SIZE			0x8 +#define SSC_RXFIFO_SIZE			0x8 + +enum st_i2c_mode { +	I2C_MODE_STANDARD, +	I2C_MODE_FAST, +	I2C_MODE_END, +}; + +/** + * struct st_i2c_timings - per-Mode tuning parameters + * @rate: I2C bus rate + * @rep_start_hold: I2C repeated start hold time requirement + * @rep_start_setup: I2C repeated start set up time requirement + * @start_hold: I2C start hold time requirement + * @data_setup_time: I2C data set up time requirement + * @stop_setup_time: I2C stop set up time requirement + * @bus_free_time: I2C bus free time requirement + * @sda_pulse_min_limit: I2C SDA pulse mini width limit + */ +struct st_i2c_timings { +	u32 rate; +	u32 rep_start_hold; +	u32 rep_start_setup; +	u32 start_hold; +	u32 data_setup_time; +	u32 stop_setup_time; +	u32 bus_free_time; +	u32 sda_pulse_min_limit; +}; + +/** + * struct st_i2c_client - client specific data + * @addr: 8-bit slave addr, including r/w bit + * @count: number of bytes to be transfered + * @xfered: number of bytes already transferred + * @buf: data buffer + * @result: result of the transfer + * @stop: last I2C msg to be sent, i.e. STOP to be generated + */ +struct st_i2c_client { +	u8	addr; +	u32	count; +	u32	xfered; +	u8	*buf; +	int	result; +	bool	stop; +}; + +/** + * struct st_i2c_dev - private data of the controller + * @adap: I2C adapter for this controller + * @dev: device for this controller + * @base: virtual memory area + * @complete: completion of I2C message + * @irq: interrupt line for th controller + * @clk: hw ssc block clock + * @mode: I2C mode of the controller. Standard or Fast only supported + * @scl_min_width_us: SCL line minimum pulse width in us + * @sda_min_width_us: SDA line minimum pulse width in us + * @client: I2C transfert information + * @busy: I2C transfer on-going + */ +struct st_i2c_dev { +	struct i2c_adapter	adap; +	struct device		*dev; +	void __iomem		*base; +	struct completion	complete; +	int			irq; +	struct clk		*clk; +	int			mode; +	u32			scl_min_width_us; +	u32			sda_min_width_us; +	struct st_i2c_client	client; +	bool			busy; +}; + +static inline void st_i2c_set_bits(void __iomem *reg, u32 mask) +{ +	writel_relaxed(readl_relaxed(reg) | mask, reg); +} + +static inline void st_i2c_clr_bits(void __iomem *reg, u32 mask) +{ +	writel_relaxed(readl_relaxed(reg) & ~mask, reg); +} + +/* From I2C Specifications v0.5 */ +static struct st_i2c_timings i2c_timings[] = { +	[I2C_MODE_STANDARD] = { +		.rate			= 100000, +		.rep_start_hold		= 4000, +		.rep_start_setup	= 4700, +		.start_hold		= 4000, +		.data_setup_time	= 250, +		.stop_setup_time	= 4000, +		.bus_free_time		= 4700, +	}, +	[I2C_MODE_FAST] = { +		.rate			= 400000, +		.rep_start_hold		= 600, +		.rep_start_setup	= 600, +		.start_hold		= 600, +		.data_setup_time	= 100, +		.stop_setup_time	= 600, +		.bus_free_time		= 1300, +	}, +}; + +static void st_i2c_flush_rx_fifo(struct st_i2c_dev *i2c_dev) +{ +	int count, i; + +	/* +	 * Counter only counts up to 7 but fifo size is 8... +	 * When fifo is full, counter is 0 and RIR bit of status register is +	 * set +	 */ +	if (readl_relaxed(i2c_dev->base + SSC_STA) & SSC_STA_RIR) +		count = SSC_RXFIFO_SIZE; +	else +		count = readl_relaxed(i2c_dev->base + SSC_RX_FSTAT) & +			SSC_RX_FSTAT_STATUS; + +	for (i = 0; i < count; i++) +		readl_relaxed(i2c_dev->base + SSC_RBUF); +} + +static void st_i2c_soft_reset(struct st_i2c_dev *i2c_dev) +{ +	/* +	 * FIFO needs to be emptied before reseting the IP, +	 * else the controller raises a BUSY error. +	 */ +	st_i2c_flush_rx_fifo(i2c_dev); + +	st_i2c_set_bits(i2c_dev->base + SSC_CTL, SSC_CTL_SR); +	st_i2c_clr_bits(i2c_dev->base + SSC_CTL, SSC_CTL_SR); +} + +/** + * st_i2c_hw_config() - Prepare SSC block, calculate and apply tuning timings + * @i2c_dev: Controller's private data + */ +static void st_i2c_hw_config(struct st_i2c_dev *i2c_dev) +{ +	unsigned long rate; +	u32 val, ns_per_clk; +	struct st_i2c_timings *t = &i2c_timings[i2c_dev->mode]; + +	st_i2c_soft_reset(i2c_dev); + +	val = SSC_CLR_REPSTRT | SSC_CLR_NACK | SSC_CLR_SSCARBL | +		SSC_CLR_SSCAAS | SSC_CLR_SSCSTOP; +	writel_relaxed(val, i2c_dev->base + SSC_CLR); + +	/* SSC Control register setup */ +	val = SSC_CTL_PO | SSC_CTL_PH | SSC_CTL_HB | SSC_CTL_DATA_WIDTH_9; +	writel_relaxed(val, i2c_dev->base + SSC_CTL); + +	rate = clk_get_rate(i2c_dev->clk); +	ns_per_clk = 1000000000 / rate; + +	/* Baudrate */ +	val = rate / (2 * t->rate); +	writel_relaxed(val, i2c_dev->base + SSC_BRG); + +	/* Pre-scaler baudrate */ +	writel_relaxed(1, i2c_dev->base + SSC_PRE_SCALER_BRG); + +	/* Enable I2C mode */ +	writel_relaxed(SSC_I2C_I2CM, i2c_dev->base + SSC_I2C); + +	/* Repeated start hold time */ +	val = t->rep_start_hold / ns_per_clk; +	writel_relaxed(val, i2c_dev->base + SSC_REP_START_HOLD); + +	/* Repeated start set up time */ +	val = t->rep_start_setup / ns_per_clk; +	writel_relaxed(val, i2c_dev->base + SSC_REP_START_SETUP); + +	/* Start hold time */ +	val = t->start_hold / ns_per_clk; +	writel_relaxed(val, i2c_dev->base + SSC_START_HOLD); + +	/* Data set up time */ +	val = t->data_setup_time / ns_per_clk; +	writel_relaxed(val, i2c_dev->base + SSC_DATA_SETUP); + +	/* Stop set up time */ +	val = t->stop_setup_time / ns_per_clk; +	writel_relaxed(val, i2c_dev->base + SSC_STOP_SETUP); + +	/* Bus free time */ +	val = t->bus_free_time / ns_per_clk; +	writel_relaxed(val, i2c_dev->base + SSC_BUS_FREE); + +	/* Prescalers set up */ +	val = rate / 10000000; +	writel_relaxed(val, i2c_dev->base + SSC_PRSCALER); +	writel_relaxed(val, i2c_dev->base + SSC_PRSCALER_DATAOUT); + +	/* Noise suppression witdh */ +	val = i2c_dev->scl_min_width_us * rate / 100000000; +	writel_relaxed(val, i2c_dev->base + SSC_NOISE_SUPP_WIDTH); + +	/* Noise suppression max output data delay width */ +	val = i2c_dev->sda_min_width_us * rate / 100000000; +	writel_relaxed(val, i2c_dev->base + SSC_NOISE_SUPP_WIDTH_DATAOUT); +} + +static int st_i2c_wait_free_bus(struct st_i2c_dev *i2c_dev) +{ +	u32 sta; +	int i; + +	for (i = 0; i < 10; i++) { +		sta = readl_relaxed(i2c_dev->base + SSC_STA); +		if (!(sta & SSC_STA_BUSY)) +			return 0; + +		usleep_range(2000, 4000); +	} + +	dev_err(i2c_dev->dev, "bus not free (status = 0x%08x)\n", sta); + +	return -EBUSY; +} + +/** + * st_i2c_write_tx_fifo() - Write a byte in the Tx FIFO + * @i2c_dev: Controller's private data + * @byte: Data to write in the Tx FIFO + */ +static inline void st_i2c_write_tx_fifo(struct st_i2c_dev *i2c_dev, u8 byte) +{ +	u16 tbuf = byte << 1; + +	writel_relaxed(tbuf | 1, i2c_dev->base + SSC_TBUF); +} + +/** + * st_i2c_wr_fill_tx_fifo() - Fill the Tx FIFO in write mode + * @i2c_dev: Controller's private data + * + * This functions fills the Tx FIFO with I2C transfert buffer when + * in write mode. + */ +static void st_i2c_wr_fill_tx_fifo(struct st_i2c_dev *i2c_dev) +{ +	struct st_i2c_client *c = &i2c_dev->client; +	u32 tx_fstat, sta; +	int i; + +	sta = readl_relaxed(i2c_dev->base + SSC_STA); +	if (sta & SSC_STA_TX_FIFO_FULL) +		return; + +	tx_fstat = readl_relaxed(i2c_dev->base + SSC_TX_FSTAT); +	tx_fstat &= SSC_TX_FSTAT_STATUS; + +	if (c->count < (SSC_TXFIFO_SIZE - tx_fstat)) +		i = c->count; +	else +		i = SSC_TXFIFO_SIZE - tx_fstat; + +	for (; i > 0; i--, c->count--, c->buf++) +		st_i2c_write_tx_fifo(i2c_dev, *c->buf); +} + +/** + * st_i2c_rd_fill_tx_fifo() - Fill the Tx FIFO in read mode + * @i2c_dev: Controller's private data + * + * This functions fills the Tx FIFO with fixed pattern when + * in read mode to trigger clock. + */ +static void st_i2c_rd_fill_tx_fifo(struct st_i2c_dev *i2c_dev, int max) +{ +	struct st_i2c_client *c = &i2c_dev->client; +	u32 tx_fstat, sta; +	int i; + +	sta = readl_relaxed(i2c_dev->base + SSC_STA); +	if (sta & SSC_STA_TX_FIFO_FULL) +		return; + +	tx_fstat = readl_relaxed(i2c_dev->base + SSC_TX_FSTAT); +	tx_fstat &= SSC_TX_FSTAT_STATUS; + +	if (max < (SSC_TXFIFO_SIZE - tx_fstat)) +		i = max; +	else +		i = SSC_TXFIFO_SIZE - tx_fstat; + +	for (; i > 0; i--, c->xfered++) +		st_i2c_write_tx_fifo(i2c_dev, 0xff); +} + +static void st_i2c_read_rx_fifo(struct st_i2c_dev *i2c_dev) +{ +	struct st_i2c_client *c = &i2c_dev->client; +	u32 i, sta; +	u16 rbuf; + +	sta = readl_relaxed(i2c_dev->base + SSC_STA); +	if (sta & SSC_STA_RIR) { +		i = SSC_RXFIFO_SIZE; +	} else { +		i = readl_relaxed(i2c_dev->base + SSC_RX_FSTAT); +		i &= SSC_RX_FSTAT_STATUS; +	} + +	for (; (i > 0) && (c->count > 0); i--, c->count--) { +		rbuf = readl_relaxed(i2c_dev->base + SSC_RBUF) >> 1; +		*c->buf++ = (u8)rbuf & 0xff; +	} + +	if (i) { +		dev_err(i2c_dev->dev, "Unexpected %d bytes in rx fifo\n", i); +		st_i2c_flush_rx_fifo(i2c_dev); +	} +} + +/** + * st_i2c_terminate_xfer() - Send either STOP or REPSTART condition + * @i2c_dev: Controller's private data + */ +static void st_i2c_terminate_xfer(struct st_i2c_dev *i2c_dev) +{ +	struct st_i2c_client *c = &i2c_dev->client; + +	st_i2c_clr_bits(i2c_dev->base + SSC_IEN, SSC_IEN_TEEN); +	st_i2c_clr_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STRTG); + +	if (c->stop) { +		st_i2c_set_bits(i2c_dev->base + SSC_IEN, SSC_IEN_STOPEN); +		st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STOPG); +	} else { +		st_i2c_set_bits(i2c_dev->base + SSC_IEN, SSC_IEN_REPSTRTEN); +		st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_REPSTRTG); +	} +} + +/** + * st_i2c_handle_write() - Handle FIFO empty interrupt in case of write + * @i2c_dev: Controller's private data + */ +static void st_i2c_handle_write(struct st_i2c_dev *i2c_dev) +{ +	struct st_i2c_client *c = &i2c_dev->client; + +	st_i2c_flush_rx_fifo(i2c_dev); + +	if (!c->count) +		/* End of xfer, send stop or repstart */ +		st_i2c_terminate_xfer(i2c_dev); +	else +		st_i2c_wr_fill_tx_fifo(i2c_dev); +} + +/** + * st_i2c_handle_write() - Handle FIFO enmpty interrupt in case of read + * @i2c_dev: Controller's private data + */ +static void st_i2c_handle_read(struct st_i2c_dev *i2c_dev) +{ +	struct st_i2c_client *c = &i2c_dev->client; +	u32 ien; + +	/* Trash the address read back */ +	if (!c->xfered) { +		readl_relaxed(i2c_dev->base + SSC_RBUF); +		st_i2c_clr_bits(i2c_dev->base + SSC_I2C, SSC_I2C_TXENB); +	} else { +		st_i2c_read_rx_fifo(i2c_dev); +	} + +	if (!c->count) { +		/* End of xfer, send stop or repstart */ +		st_i2c_terminate_xfer(i2c_dev); +	} else if (c->count == 1) { +		/* Penultimate byte to xfer, disable ACK gen. */ +		st_i2c_clr_bits(i2c_dev->base + SSC_I2C, SSC_I2C_ACKG); + +		/* Last received byte is to be handled by NACK interrupt */ +		ien = SSC_IEN_NACKEN | SSC_IEN_ARBLEN; +		writel_relaxed(ien, i2c_dev->base + SSC_IEN); + +		st_i2c_rd_fill_tx_fifo(i2c_dev, c->count); +	} else { +		st_i2c_rd_fill_tx_fifo(i2c_dev, c->count - 1); +	} +} + +/** + * st_i2c_isr() - Interrupt routine + * @irq: interrupt number + * @data: Controller's private data + */ +static irqreturn_t st_i2c_isr_thread(int irq, void *data) +{ +	struct st_i2c_dev *i2c_dev = data; +	struct st_i2c_client *c = &i2c_dev->client; +	u32 sta, ien; +	int it; + +	ien = readl_relaxed(i2c_dev->base + SSC_IEN); +	sta = readl_relaxed(i2c_dev->base + SSC_STA); + +	/* Use __fls() to check error bits first */ +	it = __fls(sta & ien); +	if (it < 0) { +		dev_dbg(i2c_dev->dev, "spurious it (sta=0x%04x, ien=0x%04x)\n", +				sta, ien); +		return IRQ_NONE; +	} + +	switch (1 << it) { +	case SSC_STA_TE: +		if (c->addr & I2C_M_RD) +			st_i2c_handle_read(i2c_dev); +		else +			st_i2c_handle_write(i2c_dev); +		break; + +	case SSC_STA_STOP: +	case SSC_STA_REPSTRT: +		writel_relaxed(0, i2c_dev->base + SSC_IEN); +		complete(&i2c_dev->complete); +		break; + +	case SSC_STA_NACK: +		writel_relaxed(SSC_CLR_NACK, i2c_dev->base + SSC_CLR); + +		/* Last received byte handled by NACK interrupt */ +		if ((c->addr & I2C_M_RD) && (c->count == 1) && (c->xfered)) { +			st_i2c_handle_read(i2c_dev); +			break; +		} + +		it = SSC_IEN_STOPEN | SSC_IEN_ARBLEN; +		writel_relaxed(it, i2c_dev->base + SSC_IEN); + +		st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STOPG); +		c->result = -EIO; +		break; + +	case SSC_STA_ARBL: +		writel_relaxed(SSC_CLR_SSCARBL, i2c_dev->base + SSC_CLR); + +		it = SSC_IEN_STOPEN | SSC_IEN_ARBLEN; +		writel_relaxed(it, i2c_dev->base + SSC_IEN); + +		st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STOPG); +		c->result = -EAGAIN; +		break; + +	default: +		dev_err(i2c_dev->dev, +				"it %d unhandled (sta=0x%04x)\n", it, sta); +	} + +	/* +	 * Read IEN register to ensure interrupt mask write is effective +	 * before re-enabling interrupt at GIC level, and thus avoid spurious +	 * interrupts. +	 */ +	readl(i2c_dev->base + SSC_IEN); + +	return IRQ_HANDLED; +} + +/** + * st_i2c_xfer_msg() - Transfer a single I2C message + * @i2c_dev: Controller's private data + * @msg: I2C message to transfer + * @is_first: first message of the sequence + * @is_last: last message of the sequence + */ +static int st_i2c_xfer_msg(struct st_i2c_dev *i2c_dev, struct i2c_msg *msg, +			    bool is_first, bool is_last) +{ +	struct st_i2c_client *c = &i2c_dev->client; +	u32 ctl, i2c, it; +	unsigned long timeout; +	int ret; + +	c->addr		= (u8)(msg->addr << 1); +	c->addr		|= (msg->flags & I2C_M_RD); +	c->buf		= msg->buf; +	c->count	= msg->len; +	c->xfered	= 0; +	c->result	= 0; +	c->stop		= is_last; + +	reinit_completion(&i2c_dev->complete); + +	ctl = SSC_CTL_EN | SSC_CTL_MS |	SSC_CTL_EN_RX_FIFO | SSC_CTL_EN_TX_FIFO; +	st_i2c_set_bits(i2c_dev->base + SSC_CTL, ctl); + +	i2c = SSC_I2C_TXENB; +	if (c->addr & I2C_M_RD) +		i2c |= SSC_I2C_ACKG; +	st_i2c_set_bits(i2c_dev->base + SSC_I2C, i2c); + +	/* Write slave address */ +	st_i2c_write_tx_fifo(i2c_dev, c->addr); + +	/* Pre-fill Tx fifo with data in case of write */ +	if (!(c->addr & I2C_M_RD)) +		st_i2c_wr_fill_tx_fifo(i2c_dev); + +	it = SSC_IEN_NACKEN | SSC_IEN_TEEN | SSC_IEN_ARBLEN; +	writel_relaxed(it, i2c_dev->base + SSC_IEN); + +	if (is_first) { +		ret = st_i2c_wait_free_bus(i2c_dev); +		if (ret) +			return ret; + +		st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STRTG); +	} + +	timeout = wait_for_completion_timeout(&i2c_dev->complete, +			i2c_dev->adap.timeout); +	ret = c->result; + +	if (!timeout) { +		dev_err(i2c_dev->dev, "Write to slave 0x%x timed out\n", +				c->addr); +		ret = -ETIMEDOUT; +	} + +	i2c = SSC_I2C_STOPG | SSC_I2C_REPSTRTG; +	st_i2c_clr_bits(i2c_dev->base + SSC_I2C, i2c); + +	writel_relaxed(SSC_CLR_SSCSTOP | SSC_CLR_REPSTRT, +			i2c_dev->base + SSC_CLR); + +	return ret; +} + +/** + * st_i2c_xfer() - Transfer a single I2C message + * @i2c_adap: Adapter pointer to the controller + * @msgs: Pointer to data to be written. + * @num: Number of messages to be executed + */ +static int st_i2c_xfer(struct i2c_adapter *i2c_adap, +			struct i2c_msg msgs[], int num) +{ +	struct st_i2c_dev *i2c_dev = i2c_get_adapdata(i2c_adap); +	int ret, i; + +	i2c_dev->busy = true; + +	ret = clk_prepare_enable(i2c_dev->clk); +	if (ret) { +		dev_err(i2c_dev->dev, "Failed to prepare_enable clock\n"); +		return ret; +	} + +	pinctrl_pm_select_default_state(i2c_dev->dev); + +	st_i2c_hw_config(i2c_dev); + +	for (i = 0; (i < num) && !ret; i++) +		ret = st_i2c_xfer_msg(i2c_dev, &msgs[i], i == 0, i == num - 1); + +	pinctrl_pm_select_idle_state(i2c_dev->dev); + +	clk_disable_unprepare(i2c_dev->clk); + +	i2c_dev->busy = false; + +	return (ret < 0) ? ret : i; +} + +#ifdef CONFIG_PM_SLEEP +static int st_i2c_suspend(struct device *dev) +{ +	struct platform_device *pdev = +		container_of(dev, struct platform_device, dev); +	struct st_i2c_dev *i2c_dev = platform_get_drvdata(pdev); + +	if (i2c_dev->busy) +		return -EBUSY; + +	pinctrl_pm_select_sleep_state(dev); + +	return 0; +} + +static int st_i2c_resume(struct device *dev) +{ +	pinctrl_pm_select_default_state(dev); +	/* Go in idle state if available */ +	pinctrl_pm_select_idle_state(dev); + +	return 0; +} + +static SIMPLE_DEV_PM_OPS(st_i2c_pm, st_i2c_suspend, st_i2c_resume); +#define ST_I2C_PM	(&st_i2c_pm) +#else +#define ST_I2C_PM	NULL +#endif + +static u32 st_i2c_func(struct i2c_adapter *adap) +{ +	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static struct i2c_algorithm st_i2c_algo = { +	.master_xfer = st_i2c_xfer, +	.functionality = st_i2c_func, +}; + +static int st_i2c_of_get_deglitch(struct device_node *np, +		struct st_i2c_dev *i2c_dev) +{ +	int ret; + +	ret = of_property_read_u32(np, "st,i2c-min-scl-pulse-width-us", +			&i2c_dev->scl_min_width_us); +	if ((ret == -ENODATA) || (ret == -EOVERFLOW)) { +		dev_err(i2c_dev->dev, "st,i2c-min-scl-pulse-width-us invalid\n"); +		return ret; +	} + +	ret = of_property_read_u32(np, "st,i2c-min-sda-pulse-width-us", +			&i2c_dev->sda_min_width_us); +	if ((ret == -ENODATA) || (ret == -EOVERFLOW)) { +		dev_err(i2c_dev->dev, "st,i2c-min-sda-pulse-width-us invalid\n"); +		return ret; +	} + +	return 0; +} + +static int st_i2c_probe(struct platform_device *pdev) +{ +	struct device_node *np = pdev->dev.of_node; +	struct st_i2c_dev *i2c_dev; +	struct resource *res; +	u32 clk_rate; +	struct i2c_adapter *adap; +	int ret; + +	i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); +	if (!i2c_dev) +		return -ENOMEM; + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	i2c_dev->base = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(i2c_dev->base)) +		return PTR_ERR(i2c_dev->base); + +	i2c_dev->irq = irq_of_parse_and_map(np, 0); +	if (!i2c_dev->irq) { +		dev_err(&pdev->dev, "IRQ missing or invalid\n"); +		return -EINVAL; +	} + +	i2c_dev->clk = of_clk_get_by_name(np, "ssc"); +	if (IS_ERR(i2c_dev->clk)) { +		dev_err(&pdev->dev, "Unable to request clock\n"); +		return PTR_ERR(i2c_dev->clk); +	} + +	i2c_dev->mode = I2C_MODE_STANDARD; +	ret = of_property_read_u32(np, "clock-frequency", &clk_rate); +	if ((!ret) && (clk_rate == 400000)) +		i2c_dev->mode = I2C_MODE_FAST; + +	i2c_dev->dev = &pdev->dev; + +	ret = devm_request_threaded_irq(&pdev->dev, i2c_dev->irq, +			NULL, st_i2c_isr_thread, +			IRQF_ONESHOT, pdev->name, i2c_dev); +	if (ret) { +		dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq); +		return ret; +	} + +	pinctrl_pm_select_default_state(i2c_dev->dev); +	/* In case idle state available, select it */ +	pinctrl_pm_select_idle_state(i2c_dev->dev); + +	ret = st_i2c_of_get_deglitch(np, i2c_dev); +	if (ret) +		return ret; + +	adap = &i2c_dev->adap; +	i2c_set_adapdata(adap, i2c_dev); +	snprintf(adap->name, sizeof(adap->name), "ST I2C(0x%x)", res->start); +	adap->owner = THIS_MODULE; +	adap->timeout = 2 * HZ; +	adap->retries = 0; +	adap->algo = &st_i2c_algo; +	adap->dev.parent = &pdev->dev; +	adap->dev.of_node = pdev->dev.of_node; + +	init_completion(&i2c_dev->complete); + +	ret = i2c_add_adapter(adap); +	if (ret) { +		dev_err(&pdev->dev, "Failed to add adapter\n"); +		return ret; +	} + +	platform_set_drvdata(pdev, i2c_dev); + +	dev_info(i2c_dev->dev, "%s initialized\n", adap->name); + +	return 0; +} + +static int st_i2c_remove(struct platform_device *pdev) +{ +	struct st_i2c_dev *i2c_dev = platform_get_drvdata(pdev); + +	i2c_del_adapter(&i2c_dev->adap); + +	return 0; +} + +static const struct of_device_id st_i2c_match[] = { +	{ .compatible = "st,comms-ssc-i2c", }, +	{ .compatible = "st,comms-ssc4-i2c", }, +	{}, +}; +MODULE_DEVICE_TABLE(of, st_i2c_match); + +static struct platform_driver st_i2c_driver = { +	.driver = { +		.name = "st-i2c", +		.owner = THIS_MODULE, +		.of_match_table = st_i2c_match, +		.pm = ST_I2C_PM, +	}, +	.probe = st_i2c_probe, +	.remove = st_i2c_remove, +}; + +module_platform_driver(st_i2c_driver); + +MODULE_AUTHOR("Maxime Coquelin <maxime.coquelin@st.com>"); +MODULE_DESCRIPTION("STMicroelectronics I2C driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c index f8f6f2e552d..fefb1c19ec1 100644 --- a/drivers/i2c/busses/i2c-stu300.c +++ b/drivers/i2c/busses/i2c-stu300.c @@ -801,7 +801,7 @@ static int stu300_xfer_msg(struct i2c_adapter *adap,  	/* Check that the bus is free, or wait until some timeout occurs */  	ret = stu300_wait_while_busy(dev);  	if (ret != 0) { -		dev_err(&dev->pdev->dev, "timout waiting for transfer " +		dev_err(&dev->pdev->dev, "timeout waiting for transfer "  		       "to commence.\n");  		goto exit_disable;  	} @@ -859,8 +859,7 @@ static const struct i2c_algorithm stu300_algo = {  	.functionality	= stu300_func,  }; -static int __init -stu300_probe(struct platform_device *pdev) +static int stu300_probe(struct platform_device *pdev)  {  	struct stu300_dev *dev;  	struct i2c_adapter *adap; @@ -869,10 +868,8 @@ stu300_probe(struct platform_device *pdev)  	int ret = 0;  	dev = devm_kzalloc(&pdev->dev, sizeof(struct stu300_dev), GFP_KERNEL); -	if (!dev) { -		dev_err(&pdev->dev, "could not allocate device struct\n"); +	if (!dev)  		return -ENOMEM; -	}  	bus_nr = pdev->id;  	dev->clk = devm_clk_get(&pdev->dev, NULL); @@ -912,7 +909,7 @@ stu300_probe(struct platform_device *pdev)  	adap = &dev->adapter;  	adap->owner = THIS_MODULE;  	/* DDC class but actually often used for more generic I2C */ -	adap->class = I2C_CLASS_DDC; +	adap->class = I2C_CLASS_DDC | I2C_CLASS_DEPRECATED;  	strlcpy(adap->name, "ST Microelectronics DDC I2C adapter",  		sizeof(adap->name));  	adap->nr = bus_nr; @@ -966,8 +963,7 @@ static SIMPLE_DEV_PM_OPS(stu300_pm, stu300_suspend, stu300_resume);  #define STU300_I2C_PM	NULL  #endif -static int __exit -stu300_remove(struct platform_device *pdev) +static int stu300_remove(struct platform_device *pdev)  {  	struct stu300_dev *dev = platform_get_drvdata(pdev); @@ -989,13 +985,14 @@ static struct platform_driver stu300_i2c_driver = {  		.pm	= STU300_I2C_PM,  		.of_match_table = stu300_dt_match,  	}, -	.remove		= __exit_p(stu300_remove), +	.probe = stu300_probe, +	.remove = stu300_remove,  };  static int __init stu300_init(void)  { -	return platform_driver_probe(&stu300_i2c_driver, stu300_probe); +	return platform_driver_register(&stu300_i2c_driver);  }  static void __exit stu300_exit(void) diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c new file mode 100644 index 00000000000..4d75d475970 --- /dev/null +++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c @@ -0,0 +1,344 @@ +/* + * P2WI (Push-Pull Two Wire Interface) bus driver. + * + * Author: Boris BREZILLON <boris.brezillon@free-electrons.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. + * + * The P2WI controller looks like an SMBus controller which only supports byte + * data transfers. But, it differs from standard SMBus protocol on several + * aspects: + * - it supports only one slave device, and thus drop the address field + * - it adds a parity bit every 8bits of data + * - only one read access is required to read a byte (instead of a write + *   followed by a read access in standard SMBus protocol) + * - there's no Ack bit after each byte transfer + * + * This means this bus cannot be used to interface with standard SMBus + * devices (the only known device to support this interface is the AXP221 + * PMIC). + * + */ +#include <linux/clk.h> +#include <linux/i2c.h> +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/reset.h> + + +/* P2WI registers */ +#define P2WI_CTRL		0x0 +#define P2WI_CCR		0x4 +#define P2WI_INTE		0x8 +#define P2WI_INTS		0xc +#define P2WI_DADDR0		0x10 +#define P2WI_DADDR1		0x14 +#define P2WI_DLEN		0x18 +#define P2WI_DATA0		0x1c +#define P2WI_DATA1		0x20 +#define P2WI_LCR		0x24 +#define P2WI_PMCR		0x28 + +/* CTRL fields */ +#define P2WI_CTRL_START_TRANS		BIT(7) +#define P2WI_CTRL_ABORT_TRANS		BIT(6) +#define P2WI_CTRL_GLOBAL_INT_ENB	BIT(1) +#define P2WI_CTRL_SOFT_RST		BIT(0) + +/* CLK CTRL fields */ +#define P2WI_CCR_SDA_OUT_DELAY(v)	(((v) & 0x7) << 8) +#define P2WI_CCR_MAX_CLK_DIV		0xff +#define P2WI_CCR_CLK_DIV(v)		((v) & P2WI_CCR_MAX_CLK_DIV) + +/* STATUS fields */ +#define P2WI_INTS_TRANS_ERR_ID(v)	(((v) >> 8) & 0xff) +#define P2WI_INTS_LOAD_BSY		BIT(2) +#define P2WI_INTS_TRANS_ERR		BIT(1) +#define P2WI_INTS_TRANS_OVER		BIT(0) + +/* DATA LENGTH fields*/ +#define P2WI_DLEN_READ			BIT(4) +#define P2WI_DLEN_DATA_LENGTH(v)	((v - 1) & 0x7) + +/* LINE CTRL fields*/ +#define P2WI_LCR_SCL_STATE		BIT(5) +#define P2WI_LCR_SDA_STATE		BIT(4) +#define P2WI_LCR_SCL_CTL		BIT(3) +#define P2WI_LCR_SCL_CTL_EN		BIT(2) +#define P2WI_LCR_SDA_CTL		BIT(1) +#define P2WI_LCR_SDA_CTL_EN		BIT(0) + +/* PMU MODE CTRL fields */ +#define P2WI_PMCR_PMU_INIT_SEND		BIT(31) +#define P2WI_PMCR_PMU_INIT_DATA(v)	(((v) & 0xff) << 16) +#define P2WI_PMCR_PMU_MODE_REG(v)	(((v) & 0xff) << 8) +#define P2WI_PMCR_PMU_DEV_ADDR(v)	((v) & 0xff) + +#define P2WI_MAX_FREQ			6000000 + +struct p2wi { +	struct i2c_adapter adapter; +	struct completion complete; +	unsigned int status; +	void __iomem *regs; +	struct clk *clk; +	struct reset_control *rstc; +	int slave_addr; +}; + +static irqreturn_t p2wi_interrupt(int irq, void *dev_id) +{ +	struct p2wi *p2wi = dev_id; +	unsigned long status; + +	status = readl(p2wi->regs + P2WI_INTS); +	p2wi->status = status; + +	/* Clear interrupts */ +	status &= (P2WI_INTS_LOAD_BSY | P2WI_INTS_TRANS_ERR | +		   P2WI_INTS_TRANS_OVER); +	writel(status, p2wi->regs + P2WI_INTS); + +	complete(&p2wi->complete); + +	return IRQ_HANDLED; +} + +static u32 p2wi_functionality(struct i2c_adapter *adap) +{ +	return I2C_FUNC_SMBUS_BYTE_DATA; +} + +static int p2wi_smbus_xfer(struct i2c_adapter *adap, u16 addr, +			   unsigned short flags, char read_write, +			   u8 command, int size, union i2c_smbus_data *data) +{ +	struct p2wi *p2wi = i2c_get_adapdata(adap); +	unsigned long dlen = P2WI_DLEN_DATA_LENGTH(1); + +	if (p2wi->slave_addr >= 0 && addr != p2wi->slave_addr) { +		dev_err(&adap->dev, "invalid P2WI address\n"); +		return -EINVAL; +	} + +	if (!data) +		return -EINVAL; + +	writel(command, p2wi->regs + P2WI_DADDR0); + +	if (read_write == I2C_SMBUS_READ) +		dlen |= P2WI_DLEN_READ; +	else +		writel(data->byte, p2wi->regs + P2WI_DATA0); + +	writel(dlen, p2wi->regs + P2WI_DLEN); + +	if (readl(p2wi->regs + P2WI_CTRL) & P2WI_CTRL_START_TRANS) { +		dev_err(&adap->dev, "P2WI bus busy\n"); +		return -EBUSY; +	} + +	reinit_completion(&p2wi->complete); + +	writel(P2WI_INTS_LOAD_BSY | P2WI_INTS_TRANS_ERR | P2WI_INTS_TRANS_OVER, +	       p2wi->regs + P2WI_INTE); + +	writel(P2WI_CTRL_START_TRANS | P2WI_CTRL_GLOBAL_INT_ENB, +	       p2wi->regs + P2WI_CTRL); + +	wait_for_completion(&p2wi->complete); + +	if (p2wi->status & P2WI_INTS_LOAD_BSY) { +		dev_err(&adap->dev, "P2WI bus busy\n"); +		return -EBUSY; +	} + +	if (p2wi->status & P2WI_INTS_TRANS_ERR) { +		dev_err(&adap->dev, "P2WI bus xfer error\n"); +		return -ENXIO; +	} + +	if (read_write == I2C_SMBUS_READ) +		data->byte = readl(p2wi->regs + P2WI_DATA0); + +	return 0; +} + +static const struct i2c_algorithm p2wi_algo = { +	.smbus_xfer = p2wi_smbus_xfer, +	.functionality = p2wi_functionality, +}; + +static const struct of_device_id p2wi_of_match_table[] = { +	{ .compatible = "allwinner,sun6i-a31-p2wi" }, +	{} +}; +MODULE_DEVICE_TABLE(of, p2wi_of_match_table); + +static int p2wi_probe(struct platform_device *pdev) +{ +	struct device *dev = &pdev->dev; +	struct device_node *np = dev->of_node; +	struct device_node *childnp; +	unsigned long parent_clk_freq; +	u32 clk_freq = 100000; +	struct resource *r; +	struct p2wi *p2wi; +	u32 slave_addr; +	int clk_div; +	int irq; +	int ret; + +	of_property_read_u32(np, "clock-frequency", &clk_freq); +	if (clk_freq > P2WI_MAX_FREQ) { +		dev_err(dev, +			"required clock-frequency (%u Hz) is too high (max = 6MHz)", +			clk_freq); +		return -EINVAL; +	} + +	if (of_get_child_count(np) > 1) { +		dev_err(dev, "P2WI only supports one slave device\n"); +		return -EINVAL; +	} + +	p2wi = devm_kzalloc(dev, sizeof(struct p2wi), GFP_KERNEL); +	if (!p2wi) +		return -ENOMEM; + +	p2wi->slave_addr = -1; + +	/* +	 * Authorize a p2wi node without any children to be able to use an +	 * i2c-dev from userpace. +	 * In this case the slave_addr is set to -1 and won't be checked when +	 * launching a P2WI transfer. +	 */ +	childnp = of_get_next_available_child(np, NULL); +	if (childnp) { +		ret = of_property_read_u32(childnp, "reg", &slave_addr); +		if (ret) { +			dev_err(dev, "invalid slave address on node %s\n", +				childnp->full_name); +			return -EINVAL; +		} + +		p2wi->slave_addr = slave_addr; +	} + +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	p2wi->regs = devm_ioremap_resource(dev, r); +	if (IS_ERR(p2wi->regs)) +		return PTR_ERR(p2wi->regs); + +	strlcpy(p2wi->adapter.name, pdev->name, sizeof(p2wi->adapter.name)); +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) { +		dev_err(dev, "failed to retrieve irq: %d\n", irq); +		return irq; +	} + +	p2wi->clk = devm_clk_get(dev, NULL); +	if (IS_ERR(p2wi->clk)) { +		ret = PTR_ERR(p2wi->clk); +		dev_err(dev, "failed to retrieve clk: %d\n", ret); +		return ret; +	} + +	ret = clk_prepare_enable(p2wi->clk); +	if (ret) { +		dev_err(dev, "failed to enable clk: %d\n", ret); +		return ret; +	} + +	parent_clk_freq = clk_get_rate(p2wi->clk); + +	p2wi->rstc = devm_reset_control_get(dev, NULL); +	if (IS_ERR(p2wi->rstc)) { +		ret = PTR_ERR(p2wi->rstc); +		dev_err(dev, "failed to retrieve reset controller: %d\n", ret); +		goto err_clk_disable; +	} + +	ret = reset_control_deassert(p2wi->rstc); +	if (ret) { +		dev_err(dev, "failed to deassert reset line: %d\n", ret); +		goto err_clk_disable; +	} + +	init_completion(&p2wi->complete); +	p2wi->adapter.dev.parent = dev; +	p2wi->adapter.algo = &p2wi_algo; +	p2wi->adapter.owner = THIS_MODULE; +	p2wi->adapter.dev.of_node = pdev->dev.of_node; +	platform_set_drvdata(pdev, p2wi); +	i2c_set_adapdata(&p2wi->adapter, p2wi); + +	ret = devm_request_irq(dev, irq, p2wi_interrupt, 0, pdev->name, p2wi); +	if (ret) { +		dev_err(dev, "can't register interrupt handler irq%d: %d\n", +			irq, ret); +		goto err_reset_assert; +	} + +	writel(P2WI_CTRL_SOFT_RST, p2wi->regs + P2WI_CTRL); + +	clk_div = parent_clk_freq / clk_freq; +	if (!clk_div) { +		dev_warn(dev, +			 "clock-frequency is too high, setting it to %lu Hz\n", +			 parent_clk_freq); +		clk_div = 1; +	} else if (clk_div > P2WI_CCR_MAX_CLK_DIV) { +		dev_warn(dev, +			 "clock-frequency is too low, setting it to %lu Hz\n", +			 parent_clk_freq / P2WI_CCR_MAX_CLK_DIV); +		clk_div = P2WI_CCR_MAX_CLK_DIV; +	} + +	writel(P2WI_CCR_SDA_OUT_DELAY(1) | P2WI_CCR_CLK_DIV(clk_div), +	       p2wi->regs + P2WI_CCR); + +	ret = i2c_add_adapter(&p2wi->adapter); +	if (!ret) +		return 0; + +err_reset_assert: +	reset_control_assert(p2wi->rstc); + +err_clk_disable: +	clk_disable_unprepare(p2wi->clk); + +	return ret; +} + +static int p2wi_remove(struct platform_device *dev) +{ +	struct p2wi *p2wi = platform_get_drvdata(dev); + +	reset_control_assert(p2wi->rstc); +	clk_disable_unprepare(p2wi->clk); +	i2c_del_adapter(&p2wi->adapter); + +	return 0; +} + +static struct platform_driver p2wi_driver = { +	.probe	= p2wi_probe, +	.remove	= p2wi_remove, +	.driver	= { +		.owner = THIS_MODULE, +		.name = "i2c-sunxi-p2wi", +		.of_match_table = p2wi_of_match_table, +	}, +}; +module_platform_driver(p2wi_driver); + +MODULE_AUTHOR("Boris BREZILLON <boris.brezillon@free-electrons.com>"); +MODULE_DESCRIPTION("Allwinner P2WI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/i2c/busses/i2c-taos-evm.c b/drivers/i2c/busses/i2c-taos-evm.c index 6ffa56e0851..05760268355 100644 --- a/drivers/i2c/busses/i2c-taos-evm.c +++ b/drivers/i2c/busses/i2c-taos-evm.c @@ -3,7 +3,7 @@   * These devices include an I2C master which can be controlled over the   * serial port.   * - * Copyright (C) 2007 Jean Delvare <khali@linux-fr.org> + * Copyright (C) 2007 Jean Delvare <jdelvare@suse.de>   *   * 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 @@ -321,7 +321,7 @@ static void __exit taos_exit(void)  	serio_unregister_driver(&taos_drv);  } -MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); +MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");  MODULE_DESCRIPTION("TAOS evaluation module driver");  MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index c457cb447c6..f1bb2fc0679 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -27,7 +27,7 @@  #include <linux/slab.h>  #include <linux/of_device.h>  #include <linux/module.h> -#include <linux/clk/tegra.h> +#include <linux/reset.h>  #include <asm/unaligned.h> @@ -160,6 +160,7 @@ struct tegra_i2c_dev {  	struct i2c_adapter adapter;  	struct clk *div_clk;  	struct clk *fast_clk; +	struct reset_control *rst;  	void __iomem *base;  	int cont_id;  	int irq; @@ -415,9 +416,9 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)  		return err;  	} -	tegra_periph_reset_assert(i2c_dev->div_clk); +	reset_control_assert(i2c_dev->rst);  	udelay(2); -	tegra_periph_reset_deassert(i2c_dev->div_clk); +	reset_control_deassert(i2c_dev->rst);  	if (i2c_dev->is_dvc)  		tegra_dvc_init(i2c_dev); @@ -544,7 +545,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,  	i2c_dev->msg_buf_remaining = msg->len;  	i2c_dev->msg_err = I2C_ERR_NONE;  	i2c_dev->msg_read = (msg->flags & I2C_M_RD); -	INIT_COMPLETION(i2c_dev->msg_complete); +	reinit_completion(&i2c_dev->msg_complete);  	packet_header = (0 << PACKET_HEADER0_HEADER_SIZE_SHIFT) |  			PACKET_HEADER0_PROTOCOL_I2C | @@ -731,10 +732,8 @@ static int tegra_i2c_probe(struct platform_device *pdev)  	}  	i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); -	if (!i2c_dev) { -		dev_err(&pdev->dev, "Could not allocate struct tegra_i2c_dev"); +	if (!i2c_dev)  		return -ENOMEM; -	}  	i2c_dev->base = base;  	i2c_dev->div_clk = div_clk; @@ -743,6 +742,12 @@ static int tegra_i2c_probe(struct platform_device *pdev)  	i2c_dev->cont_id = pdev->id;  	i2c_dev->dev = &pdev->dev; +	i2c_dev->rst = devm_reset_control_get(&pdev->dev, "i2c"); +	if (IS_ERR(i2c_dev->rst)) { +		dev_err(&pdev->dev, "missing controller reset"); +		return PTR_ERR(i2c_dev->rst); +	} +  	ret = of_property_read_u32(i2c_dev->dev->of_node, "clock-frequency",  					&i2c_dev->bus_clk_rate);  	if (ret) @@ -787,7 +792,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)  	i2c_set_adapdata(&i2c_dev->adapter, i2c_dev);  	i2c_dev->adapter.owner = THIS_MODULE; -	i2c_dev->adapter.class = I2C_CLASS_HWMON; +	i2c_dev->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED;  	strlcpy(i2c_dev->adapter.name, "Tegra I2C adapter",  		sizeof(i2c_dev->adapter.name));  	i2c_dev->adapter.algo = &tegra_i2c_algo; diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c index e7d3b755af3..0ed77eeff31 100644 --- a/drivers/i2c/busses/i2c-tiny-usb.c +++ b/drivers/i2c/busses/i2c-tiny-usb.c @@ -162,7 +162,6 @@ static const struct i2c_algorithm usb_algorithm = {  static const struct usb_device_id i2c_tiny_usb_table[] = {  	{ USB_DEVICE(0x0403, 0xc631) },   /* FTDI */  	{ USB_DEVICE(0x1c40, 0x0534) },   /* EZPrototypes */ -	{ USB_DEVICE(0x1964, 0x0001) },   /* Robofuzz OSIF */  	{ }                               /* Terminating entry */  }; diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c index be662511c58..f4a1ed75761 100644 --- a/drivers/i2c/busses/i2c-via.c +++ b/drivers/i2c/busses/i2c-via.c @@ -22,7 +22,6 @@  #include <linux/module.h>  #include <linux/pci.h>  #include <linux/ioport.h> -#include <linux/init.h>  #include <linux/i2c.h>  #include <linux/i2c-algo-bit.h>  #include <linux/io.h> @@ -89,7 +88,7 @@ static struct i2c_adapter vt586b_adapter = {  }; -static DEFINE_PCI_DEVICE_TABLE(vt586b_ids) = { +static const struct pci_device_id vt586b_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3) },  	{ 0, }  }; diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index b2d90e105f4..6841200b6e5 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -2,7 +2,7 @@      Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,      Philip Edelbrock <phil@netroedge.com>, Kyösti Mälkki <kmalkki@cc.hut.fi>,      Mark D. Studebaker <mdsxyz123@yahoo.com> -    Copyright (C) 2005 - 2008  Jean Delvare <khali@linux-fr.org> +    Copyright (C) 2005 - 2008  Jean Delvare <jdelvare@suse.de>      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 @@ -442,7 +442,7 @@ release_region:  	return error;  } -static DEFINE_PCI_DEVICE_TABLE(vt596_ids) = { +static const struct pci_device_id vt596_ids[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596_3),  	  .driver_data = SMBBA1 },  	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596B_3), @@ -503,7 +503,7 @@ static void __exit i2c_vt596_exit(void)  MODULE_AUTHOR("Kyosti Malkki <kmalkki@cc.hut.fi>, "  	      "Mark D. Studebaker <mdsxyz123@yahoo.com> and " -	      "Jean Delvare <khali@linux-fr.org>"); +	      "Jean Delvare <jdelvare@suse.de>");  MODULE_DESCRIPTION("vt82c596 SMBus driver");  MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-viperboard.c b/drivers/i2c/busses/i2c-viperboard.c index c68450cd8d5..7533fa34d73 100644 --- a/drivers/i2c/busses/i2c-viperboard.c +++ b/drivers/i2c/busses/i2c-viperboard.c @@ -118,8 +118,7 @@ static int vprbrd_i2c_addr(struct usb_device *usb_dev,  static int vprbrd_i2c_read(struct vprbrd *vb, struct i2c_msg *msg)  {  	int ret; -	u16 remain_len, bytes_xfer, len1, len2, -		start = 0x0000; +	u16 remain_len, len1, len2, start = 0x0000;  	struct vprbrd_i2c_read_msg *rmsg =  		(struct vprbrd_i2c_read_msg *)vb->buf; @@ -166,7 +165,6 @@ static int vprbrd_i2c_read(struct vprbrd *vb, struct i2c_msg *msg)  			rmsg->header.len3 = remain_len - 512;  			rmsg->header.len4 = 0x00;  			rmsg->header.len5 = 0x00; -			bytes_xfer = remain_len;  			remain_len = 0;  		} else if (remain_len <= 1022) {  			len1 = 512; @@ -367,7 +365,7 @@ static int vprbrd_i2c_probe(struct platform_device *pdev)  	int ret;  	int pipe; -	vb_i2c = kzalloc(sizeof(*vb_i2c), GFP_KERNEL); +	vb_i2c = devm_kzalloc(&pdev->dev, sizeof(*vb_i2c), GFP_KERNEL);  	if (vb_i2c == NULL)  		return -ENOMEM; @@ -394,14 +392,12 @@ static int vprbrd_i2c_probe(struct platform_device *pdev)  	    if (ret != 1) {  		dev_err(&pdev->dev,  			"failure setting i2c_bus_freq to %d\n", i2c_bus_freq); -		ret = -EIO; -		goto error; +		return -EIO;  	    }  	} else {  		dev_err(&pdev->dev,  			"invalid i2c_bus_freq setting:%d\n", i2c_bus_freq); -		ret = -EIO; -		goto error; +		return -EIO;  	}  	vb_i2c->i2c.dev.parent = &pdev->dev; @@ -412,10 +408,6 @@ static int vprbrd_i2c_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, vb_i2c);  	return 0; - -error: -	kfree(vb_i2c); -	return ret;  }  static int vprbrd_i2c_remove(struct platform_device *pdev) diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c index c65da3d913a..f80a38c2072 100644 --- a/drivers/i2c/busses/i2c-wmt.c +++ b/drivers/i2c/busses/i2c-wmt.c @@ -158,7 +158,7 @@ static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg,  		writew(val, i2c_dev->base + REG_CR);  	} -	INIT_COMPLETION(i2c_dev->complete); +	reinit_completion(&i2c_dev->complete);  	if (i2c_dev->mode == I2C_MODE_STANDARD)  		tcr_val = TCR_STANDARD_MODE; @@ -247,7 +247,7 @@ static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg,  		writew(val, i2c_dev->base + REG_CR);  	} -	INIT_COMPLETION(i2c_dev->complete); +	reinit_completion(&i2c_dev->complete);  	if (i2c_dev->mode == I2C_MODE_STANDARD)  		tcr_val = TCR_STANDARD_MODE; @@ -349,6 +349,7 @@ static int wmt_i2c_reset_hardware(struct wmt_i2c_dev *i2c_dev)  	err = clk_set_rate(i2c_dev->clk, 20000000);  	if (err) {  		dev_err(i2c_dev->dev, "failed to set clock = 20Mhz\n"); +		clk_disable_unprepare(i2c_dev->clk);  		return err;  	} @@ -378,10 +379,8 @@ static int wmt_i2c_probe(struct platform_device *pdev)  	u32 clk_rate;  	i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); -	if (!i2c_dev) { -		dev_err(&pdev->dev, "device memory allocation failed\n"); +	if (!i2c_dev)  		return -ENOMEM; -	}  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	i2c_dev->base = devm_ioremap_resource(&pdev->dev, res); @@ -453,7 +452,7 @@ static int wmt_i2c_remove(struct platform_device *pdev)  	return 0;  } -static struct of_device_id wmt_i2c_dt_ids[] = { +static const struct of_device_id wmt_i2c_dt_ids[] = {  	{ .compatible = "wm,wm8505-i2c" },  	{ /* Sentinel */ },  }; diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 4c8b368d463..7731f179586 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -30,8 +30,8 @@   */  #include <linux/kernel.h>  #include <linux/module.h> -#include <linux/init.h>  #include <linux/errno.h> +#include <linux/err.h>  #include <linux/delay.h>  #include <linux/platform_device.h>  #include <linux/i2c.h> @@ -40,6 +40,7 @@  #include <linux/i2c-xiic.h>  #include <linux/io.h>  #include <linux/slab.h> +#include <linux/of.h>  #define DRIVER_NAME "xiic-i2c" @@ -68,7 +69,7 @@ struct xiic_i2c {  	struct i2c_adapter	adap;  	struct i2c_msg		*tx_msg;  	spinlock_t		lock; -	unsigned int 		tx_pos; +	unsigned int		tx_pos;  	unsigned int		nmsgs;  	enum xilinx_i2c_state	state;  	struct i2c_msg		*rx_msg; @@ -271,8 +272,8 @@ static void xiic_read_rx(struct xiic_i2c *i2c)  	bytes_in_fifo = xiic_getreg8(i2c, XIIC_RFO_REG_OFFSET) + 1; -	dev_dbg(i2c->adap.dev.parent, "%s entry, bytes in fifo: %d, msg: %d" -		", SR: 0x%x, CR: 0x%x\n", +	dev_dbg(i2c->adap.dev.parent, +		"%s entry, bytes in fifo: %d, msg: %d, SR: 0x%x, CR: 0x%x\n",  		__func__, bytes_in_fifo, xiic_rx_space(i2c),  		xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),  		xiic_getreg8(i2c, XIIC_CR_REG_OFFSET)); @@ -339,9 +340,10 @@ static void xiic_process(struct xiic_i2c *i2c)  	ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);  	pend = isr & ier; -	dev_dbg(i2c->adap.dev.parent, "%s entry, IER: 0x%x, ISR: 0x%x, " -		"pend: 0x%x, SR: 0x%x, msg: %p, nmsgs: %d\n", -		__func__, ier, isr, pend, xiic_getreg8(i2c, XIIC_SR_REG_OFFSET), +	dev_dbg(i2c->adap.dev.parent, "%s: IER: 0x%x, ISR: 0x%x, pend: 0x%x\n", +		__func__, ier, isr, pend); +	dev_dbg(i2c->adap.dev.parent, "%s: SR: 0x%x, msg: %p, nmsgs: %d\n", +		__func__, xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),  		i2c->tx_msg, i2c->nmsgs);  	/* Do not processes a devices interrupts if the device has no @@ -541,9 +543,10 @@ static void xiic_start_send(struct xiic_i2c *i2c)  	xiic_irq_clr(i2c, XIIC_INTR_TX_ERROR_MASK); -	dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, len: %d, " -		"ISR: 0x%x, CR: 0x%x\n", -		__func__, msg, msg->len, xiic_getreg32(i2c, XIIC_IISR_OFFSET), +	dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, len: %d", +		__func__, msg, msg->len); +	dev_dbg(i2c->adap.dev.parent, "%s entry, ISR: 0x%x, CR: 0x%x\n", +		__func__, xiic_getreg32(i2c, XIIC_IISR_OFFSET),  		xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));  	if (!(msg->flags & I2C_M_NOSTART)) { @@ -681,7 +684,7 @@ static const struct i2c_algorithm xiic_algorithm = {  static struct i2c_adapter xiic_adapter = {  	.owner		= THIS_MODULE,  	.name		= DRIVER_NAME, -	.class		= I2C_CLASS_HWMON | I2C_CLASS_SPD, +	.class		= I2C_CLASS_HWMON | I2C_CLASS_SPD | I2C_CLASS_DEPRECATED,  	.algo		= &xiic_algorithm,  }; @@ -694,32 +697,20 @@ static int xiic_i2c_probe(struct platform_device *pdev)  	int ret, irq;  	u8 i; +	i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); +	if (!i2c) +		return -ENOMEM; +  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) -		goto resource_missing; +	i2c->base = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(i2c->base)) +		return PTR_ERR(i2c->base);  	irq = platform_get_irq(pdev, 0);  	if (irq < 0) -		goto resource_missing; - -	pdata = (struct xiic_i2c_platform_data *)dev_get_platdata(&pdev->dev); - -	i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); -	if (!i2c) -		return -ENOMEM; - -	if (!request_mem_region(res->start, resource_size(res), pdev->name)) { -		dev_err(&pdev->dev, "Memory region busy\n"); -		ret = -EBUSY; -		goto request_mem_failed; -	} +		return irq; -	i2c->base = ioremap(res->start, resource_size(res)); -	if (!i2c->base) { -		dev_err(&pdev->dev, "Unable to map registers\n"); -		ret = -EIO; -		goto map_failed; -	} +	pdata = dev_get_platdata(&pdev->dev);  	/* hook up driver to tree */  	platform_set_drvdata(pdev, i2c); @@ -728,21 +719,23 @@ static int xiic_i2c_probe(struct platform_device *pdev)  	i2c->adap.dev.parent = &pdev->dev;  	i2c->adap.dev.of_node = pdev->dev.of_node; -	xiic_reinit(i2c); -  	spin_lock_init(&i2c->lock);  	init_waitqueue_head(&i2c->wait); -	ret = request_irq(irq, xiic_isr, 0, pdev->name, i2c); -	if (ret) { + +	ret = devm_request_irq(&pdev->dev, irq, xiic_isr, 0, pdev->name, i2c); +	if (ret < 0) {  		dev_err(&pdev->dev, "Cannot claim IRQ\n"); -		goto request_irq_failed; +		return ret;  	} +	xiic_reinit(i2c); +  	/* add i2c adapter to i2c tree */  	ret = i2c_add_adapter(&i2c->adap);  	if (ret) {  		dev_err(&pdev->dev, "Failed to add adapter\n"); -		goto add_adapter_failed; +		xiic_deinit(i2c); +		return ret;  	}  	if (pdata) { @@ -752,43 +745,17 @@ static int xiic_i2c_probe(struct platform_device *pdev)  	}  	return 0; - -add_adapter_failed: -	free_irq(irq, i2c); -request_irq_failed: -	xiic_deinit(i2c); -	iounmap(i2c->base); -map_failed: -	release_mem_region(res->start, resource_size(res)); -request_mem_failed: -	kfree(i2c); - -	return ret; -resource_missing: -	dev_err(&pdev->dev, "IRQ or Memory resource is missing\n"); -	return -ENOENT;  }  static int xiic_i2c_remove(struct platform_device *pdev)  {  	struct xiic_i2c *i2c = platform_get_drvdata(pdev); -	struct resource *res;  	/* remove adapter & data */  	i2c_del_adapter(&i2c->adap);  	xiic_deinit(i2c); -	free_irq(platform_get_irq(pdev, 0), i2c); - -	iounmap(i2c->base); - -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (res) -		release_mem_region(res->start, resource_size(res)); - -	kfree(i2c); -  	return 0;  } diff --git a/drivers/i2c/busses/i2c-xlr.c b/drivers/i2c/busses/i2c-xlr.c index 7945b05d3ea..17f7352eca6 100644 --- a/drivers/i2c/busses/i2c-xlr.c +++ b/drivers/i2c/busses/i2c-xlr.c @@ -11,7 +11,6 @@  #include <linux/kernel.h>  #include <linux/module.h>  #include <linux/slab.h> -#include <linux/init.h>  #include <linux/ioport.h>  #include <linux/delay.h>  #include <linux/errno.h> diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 2d1d2c5653f..ff3f5747e43 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -431,10 +431,8 @@ static struct scx200_acb_iface *scx200_create_iface(const char *text,  	struct i2c_adapter *adapter;  	iface = kzalloc(sizeof(*iface), GFP_KERNEL); -	if (!iface) { -		pr_err("can't allocate memory\n"); +	if (!iface)  		return NULL; -	}  	adapter = &iface->adapter;  	i2c_set_adapdata(adapter, iface); @@ -556,7 +554,7 @@ static struct platform_driver scx200_pci_driver = {  	.remove = scx200_remove,  }; -static DEFINE_PCI_DEVICE_TABLE(scx200_isa) = { +static const struct pci_device_id scx200_isa[] = {  	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },  	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },  	{ 0, } diff --git a/drivers/i2c/busses/scx200_i2c.c b/drivers/i2c/busses/scx200_i2c.c index ae1258b95d6..8eadf0f47ad 100644 --- a/drivers/i2c/busses/scx200_i2c.c +++ b/drivers/i2c/busses/scx200_i2c.c @@ -26,7 +26,6 @@  #include <linux/module.h>  #include <linux/errno.h>  #include <linux/kernel.h> -#include <linux/init.h>  #include <linux/i2c.h>  #include <linux/i2c-algo-bit.h>  #include <linux/io.h> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 29d3f045a2b..7c7f4b856ba 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -21,7 +21,7 @@  /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.     All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>     SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and -   Jean Delvare <khali@linux-fr.org> +   Jean Delvare <jdelvare@suse.de>     Mux support by Rodolfo Giometti <giometti@enneenne.com> and     Michael Lawnick <michael.lawnick.ext@nsn.com>     OF support is copyright (c) 2008 Jochen Friedrich <jochen@scram.de> @@ -48,10 +48,13 @@  #include <linux/rwsem.h>  #include <linux/pm_runtime.h>  #include <linux/acpi.h> +#include <linux/jump_label.h>  #include <asm/uaccess.h>  #include "i2c-core.h" +#define CREATE_TRACE_POINTS +#include <trace/events/i2c.h>  /* core_lock protects i2c_adapter_idr, and guarantees     that device detection, deletion of detected devices, and attach_adapter @@ -62,6 +65,18 @@ static DEFINE_IDR(i2c_adapter_idr);  static struct device_type i2c_client_type;  static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver); +static struct static_key i2c_trace_msg = STATIC_KEY_INIT_FALSE; + +void i2c_transfer_trace_reg(void) +{ +	static_key_slow_inc(&i2c_trace_msg); +} + +void i2c_transfer_trace_unreg(void) +{ +	static_key_slow_dec(&i2c_trace_msg); +} +  /* ------------------------------------------------------------------------- */  static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id, @@ -104,6 +119,11 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)  static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)  {  	struct i2c_client	*client = to_i2c_client(dev); +	int rc; + +	rc = acpi_device_uevent_modalias(dev, env); +	if (rc != -ENODEV) +		return rc;  	if (add_uevent_var(env, "MODALIAS=%s%s",  			   I2C_MODULE_PREFIX, client->name)) @@ -248,17 +268,17 @@ static int i2c_device_probe(struct device *dev)  	driver = to_i2c_driver(dev->driver);  	if (!driver->probe || !driver->id_table)  		return -ENODEV; -	client->driver = driver; +  	if (!device_can_wakeup(&client->dev))  		device_init_wakeup(&client->dev,  					client->flags & I2C_CLIENT_WAKE);  	dev_dbg(dev, "probe\n"); +	acpi_dev_pm_attach(&client->dev, true);  	status = driver->probe(client, i2c_match_id(driver->id_table, client)); -	if (status) { -		client->driver = NULL; -		i2c_set_clientdata(client, NULL); -	} +	if (status) +		acpi_dev_pm_detach(&client->dev, true); +  	return status;  } @@ -266,7 +286,7 @@ static int i2c_device_remove(struct device *dev)  {  	struct i2c_client	*client = i2c_verify_client(dev);  	struct i2c_driver	*driver; -	int			status; +	int status = 0;  	if (!client || !dev->driver)  		return 0; @@ -275,14 +295,9 @@ static int i2c_device_remove(struct device *dev)  	if (driver->remove) {  		dev_dbg(dev, "remove\n");  		status = driver->remove(client); -	} else { -		dev->driver = NULL; -		status = 0; -	} -	if (status == 0) { -		client->driver = NULL; -		i2c_set_clientdata(client, NULL);  	} + +	acpi_dev_pm_detach(&client->dev, true);  	return status;  } @@ -409,6 +424,12 @@ static ssize_t  show_modalias(struct device *dev, struct device_attribute *attr, char *buf)  {  	struct i2c_client *client = to_i2c_client(dev); +	int len; + +	len = acpi_device_modalias(dev, buf, PAGE_SIZE -1); +	if (len != -ENODEV) +		return len; +  	return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name);  } @@ -615,6 +636,22 @@ void i2c_unlock_adapter(struct i2c_adapter *adapter)  }  EXPORT_SYMBOL_GPL(i2c_unlock_adapter); +static void i2c_dev_set_name(struct i2c_adapter *adap, +			     struct i2c_client *client) +{ +	struct acpi_device *adev = ACPI_COMPANION(&client->dev); + +	if (adev) { +		dev_set_name(&client->dev, "i2c-%s", acpi_dev_name(adev)); +		return; +	} + +	/* For 10-bit clients, add an arbitrary offset to avoid collisions */ +	dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), +		     client->addr | ((client->flags & I2C_CLIENT_TEN) +				     ? 0xa000 : 0)); +} +  /**   * i2c_new_device - instantiate an i2c device   * @adap: the adapter managing the device @@ -671,12 +708,9 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)  	client->dev.bus = &i2c_bus_type;  	client->dev.type = &i2c_client_type;  	client->dev.of_node = info->of_node; -	ACPI_HANDLE_SET(&client->dev, info->acpi_node.handle); +	ACPI_COMPANION_SET(&client->dev, info->acpi_node.companion); -	/* For 10-bit clients, add an arbitrary offset to avoid collisions */ -	dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), -		     client->addr | ((client->flags & I2C_CLIENT_TEN) -				     ? 0xa000 : 0)); +	i2c_dev_set_name(adap, client);  	status = device_register(&client->dev);  	if (status)  		goto out_err; @@ -1100,7 +1134,7 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,  		return AE_OK;  	memset(&info, 0, sizeof(info)); -	info.acpi_node.handle = handle; +	info.acpi_node.companion = adev;  	info.irq = -1;  	INIT_LIST_HEAD(&resource_list); @@ -1111,8 +1145,10 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,  	if (ret < 0 || !info.addr)  		return AE_OK; +	adev->power.flags.ignore_parent = true;  	strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type));  	if (!i2c_new_device(adapter, &info)) { +		adev->power.flags.ignore_parent = false;  		dev_err(&adapter->dev,  			"failed to add I2C device %s from ACPI\n",  			dev_name(&adev->dev)); @@ -1134,6 +1170,9 @@ static void acpi_i2c_register_devices(struct i2c_adapter *adap)  	acpi_handle handle;  	acpi_status status; +	if (!adap->dev.parent) +		return; +  	handle = ACPI_HANDLE(adap->dev.parent);  	if (!handle)  		return; @@ -1606,9 +1645,14 @@ static int i2c_cmd(struct device *dev, void *_arg)  {  	struct i2c_client	*client = i2c_verify_client(dev);  	struct i2c_cmd_arg	*arg = _arg; +	struct i2c_driver	*driver; + +	if (!client || !client->dev.driver) +		return 0; -	if (client && client->driver && client->driver->command) -		client->driver->command(client, arg->cmd, arg->arg); +	driver = to_i2c_driver(client->dev.driver); +	if (driver->command) +		driver->command(client, arg->cmd, arg->arg);  	return 0;  } @@ -1657,6 +1701,7 @@ static void __exit i2c_exit(void)  	class_compat_unregister(i2c_adapter_compat_class);  #endif  	bus_unregister(&i2c_bus_type); +	tracepoint_synchronize_unregister();  }  /* We must initialize early, because some subsystems register i2c drivers @@ -1687,6 +1732,19 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  	unsigned long orig_jiffies;  	int ret, try; +	/* i2c_trace_msg gets enabled when tracepoint i2c_transfer gets +	 * enabled.  This is an efficient way of keeping the for-loop from +	 * being executed when not needed. +	 */ +	if (static_key_false(&i2c_trace_msg)) { +		int i; +		for (i = 0; i < num; i++) +			if (msgs[i].flags & I2C_M_RD) +				trace_i2c_read(adap, &msgs[i], i); +			else +				trace_i2c_write(adap, &msgs[i], i); +	} +  	/* Retry automatically on arbitration loss */  	orig_jiffies = jiffies;  	for (ret = 0, try = 0; try <= adap->retries; try++) { @@ -1697,6 +1755,14 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  			break;  	} +	if (static_key_false(&i2c_trace_msg)) { +		int i; +		for (i = 0; i < ret; i++) +			if (msgs[i].flags & I2C_M_RD) +				trace_i2c_reply(adap, &msgs[i], i); +		trace_i2c_result(adap, i, ret); +	} +  	return ret;  }  EXPORT_SYMBOL(__i2c_transfer); @@ -1912,6 +1978,13 @@ static int i2c_detect_address(struct i2c_client *temp_client,  		struct i2c_client *client;  		/* Detection succeeded, instantiate the device */ +		if (adapter->class & I2C_CLASS_DEPRECATED) +			dev_warn(&adapter->dev, +				"This adapter will soon drop class based instantiation of devices. " +				"Please make sure client 0x%02x gets instantiated by other means. " +				"Check 'Documentation/i2c/instantiating-devices' for details.\n", +				info.addr); +  		dev_dbg(&adapter->dev, "Creating %s at 0x%02x\n",  			info.type, info.addr);  		client = i2c_new_device(adapter, &info); @@ -2492,6 +2565,14 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,  	int try;  	s32 res; +	/* If enabled, the following two tracepoints are conditional on +	 * read_write and protocol. +	 */ +	trace_smbus_write(adapter, addr, flags, read_write, +			  command, protocol, data); +	trace_smbus_read(adapter, addr, flags, read_write, +			 command, protocol); +  	flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB;  	if (adapter->algo->smbus_xfer) { @@ -2512,15 +2593,24 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,  		i2c_unlock_adapter(adapter);  		if (res != -EOPNOTSUPP || !adapter->algo->master_xfer) -			return res; +			goto trace;  		/*  		 * Fall back to i2c_smbus_xfer_emulated if the adapter doesn't  		 * implement native support for the SMBus operation.  		 */  	} -	return i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, -				       command, protocol, data); +	res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, +				      command, protocol, data); + +trace: +	/* If enabled, the reply tracepoint is conditional on read_write. */ +	trace_smbus_reply(adapter, addr, flags, read_write, +			  command, protocol, data); +	trace_smbus_result(adapter, addr, flags, read_write, +			   command, protocol, res); + +	return res;  }  EXPORT_SYMBOL(i2c_smbus_xfer); diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index c3ccdea3d18..80b47e8ce03 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -102,8 +102,8 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev)  	kfree(i2c_dev);  } -static ssize_t show_adapter_name(struct device *dev, -				 struct device_attribute *attr, char *buf) +static ssize_t name_show(struct device *dev, +			 struct device_attribute *attr, char *buf)  {  	struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(dev->devt)); @@ -111,7 +111,13 @@ static ssize_t show_adapter_name(struct device *dev,  		return -ENODEV;  	return sprintf(buf, "%s\n", i2c_dev->adap->name);  } -static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); +static DEVICE_ATTR_RO(name); + +static struct attribute *i2c_attrs[] = { +	&dev_attr_name.attr, +	NULL, +}; +ATTRIBUTE_GROUPS(i2c);  /* ------------------------------------------------------------------------- */ @@ -562,15 +568,10 @@ static int i2cdev_attach_adapter(struct device *dev, void *dummy)  		res = PTR_ERR(i2c_dev->dev);  		goto error;  	} -	res = device_create_file(i2c_dev->dev, &dev_attr_name); -	if (res) -		goto error_destroy;  	pr_debug("i2c-dev: adapter [%s] registered as minor %d\n",  		 adap->name, adap->nr);  	return 0; -error_destroy: -	device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));  error:  	return_i2c_dev(i2c_dev);  	return res; @@ -589,7 +590,6 @@ static int i2cdev_detach_adapter(struct device *dev, void *dummy)  	if (!i2c_dev) /* attach_adapter must have failed */  		return 0; -	device_remove_file(i2c_dev->dev, &dev_attr_name);  	return_i2c_dev(i2c_dev);  	device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); @@ -637,6 +637,7 @@ static int __init i2c_dev_init(void)  		res = PTR_ERR(i2c_dev_class);  		goto out_unreg_chrdev;  	} +	i2c_dev_class->dev_groups = i2c_groups;  	/* Keep track of adapters which will be added or removed later */  	res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier); diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c index 797e3117bef..2d0847b6be6 100644 --- a/drivers/i2c/i2c-mux.c +++ b/drivers/i2c/i2c-mux.c @@ -139,6 +139,8 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,  	priv->adap.algo = &priv->algo;  	priv->adap.algo_data = priv;  	priv->adap.dev.parent = &parent->dev; +	priv->adap.retries = parent->retries; +	priv->adap.timeout = parent->timeout;  	/* Sanity check on class */  	if (i2c_mux_parent_classes(parent) & class) diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c index 44d4c6071c1..fc99f0d6b4a 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c @@ -2,7 +2,7 @@   * i2c-smbus.c - SMBus extensions to the I2C protocol   *   * Copyright (C) 2008 David Brownell - * Copyright (C) 2010 Jean Delvare <khali@linux-fr.org> + * Copyright (C) 2010 Jean Delvare <jdelvare@suse.de>   *   * 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 @@ -46,6 +46,7 @@ static int smbus_do_alert(struct device *dev, void *addrp)  {  	struct i2c_client *client = i2c_verify_client(dev);  	struct alert_data *data = addrp; +	struct i2c_driver *driver;  	if (!client || client->addr != data->addr)  		return 0; @@ -54,12 +55,13 @@ static int smbus_do_alert(struct device *dev, void *addrp)  	/*  	 * Drivers should either disable alerts, or provide at least -	 * a minimal handler.  Lock so client->driver won't change. +	 * a minimal handler.  Lock so the driver won't change.  	 */  	device_lock(dev); -	if (client->driver) { -		if (client->driver->alert) -			client->driver->alert(client, data->flag); +	if (client->dev.driver) { +		driver = to_i2c_driver(client->dev.driver); +		if (driver->alert) +			driver->alert(client, data->flag);  		else  			dev_warn(&client->dev, "no driver alert()!\n");  	} else @@ -244,6 +246,6 @@ EXPORT_SYMBOL_GPL(i2c_handle_smbus_alert);  module_i2c_driver(smbalert_driver); -MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); +MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");  MODULE_DESCRIPTION("SMBus protocol extensions support");  MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/i2c-stub.c b/drivers/i2c/i2c-stub.c index d0a9c590c3c..77e4849d2f2 100644 --- a/drivers/i2c/i2c-stub.c +++ b/drivers/i2c/i2c-stub.c @@ -2,7 +2,7 @@      i2c-stub.c - I2C/SMBus chip emulator      Copyright (c) 2004 Mark M. Hoffman <mhoffman@lightlink.com> -    Copyright (C) 2007, 2012 Jean Delvare <khali@linux-fr.org> +    Copyright (C) 2007, 2012 Jean Delvare <jdelvare@suse.de>      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 diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig index f7f9865b8b8..f6d313e528d 100644 --- a/drivers/i2c/muxes/Kconfig +++ b/drivers/i2c/muxes/Kconfig @@ -40,6 +40,7 @@ config I2C_MUX_PCA9541  config I2C_MUX_PCA954x  	tristate "Philips PCA954x I2C Mux/switches" +	depends on GPIOLIB  	help  	  If you say yes here you get support for the Philips PCA954x  	  I2C mux/switch devices. diff --git a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c index 74b41ae690f..69afffa8f42 100644 --- a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c +++ b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c @@ -19,7 +19,6 @@  #include <linux/kernel.h>  #include <linux/i2c.h>  #include <linux/i2c-mux.h> -#include <linux/init.h>  #include <linux/module.h>  #include <linux/of_gpio.h>  #include <linux/platform_device.h> @@ -200,7 +199,7 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)  	arb->parent = of_find_i2c_adapter_by_node(parent_np);  	if (!arb->parent) {  		dev_err(dev, "Cannot find parent bus\n"); -		return -EINVAL; +		return -EPROBE_DEFER;  	}  	/* Actually add the mux adapter */ @@ -238,7 +237,7 @@ static struct platform_driver i2c_arbitrator_driver = {  	.driver	= {  		.owner	= THIS_MODULE,  		.name	= "i2c-arb-gpio-challenge", -		.of_match_table = of_match_ptr(i2c_arbitrator_of_match), +		.of_match_table = i2c_arbitrator_of_match,  	},  }; diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c index 5d4a99ba743..d8989c823f5 100644 --- a/drivers/i2c/muxes/i2c-mux-gpio.c +++ b/drivers/i2c/muxes/i2c-mux-gpio.c @@ -12,7 +12,6 @@  #include <linux/i2c-mux.h>  #include <linux/i2c-mux-gpio.h>  #include <linux/platform_device.h> -#include <linux/init.h>  #include <linux/module.h>  #include <linux/slab.h>  #include <linux/gpio.h> @@ -30,15 +29,15 @@ static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)  	int i;  	for (i = 0; i < mux->data.n_gpios; i++) -		gpio_set_value(mux->gpio_base + mux->data.gpios[i], -			       val & (1 << i)); +		gpio_set_value_cansleep(mux->gpio_base + mux->data.gpios[i], +					val & (1 << i));  }  static int i2c_mux_gpio_select(struct i2c_adapter *adap, void *data, u32 chan)  {  	struct gpiomux *mux = data; -	i2c_mux_gpio_set(mux, mux->data.values[chan]); +	i2c_mux_gpio_set(mux, chan);  	return 0;  } @@ -66,7 +65,7 @@ static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,  	struct device_node *adapter_np, *child;  	struct i2c_adapter *adapter;  	unsigned *values, *gpios; -	int i = 0; +	int i = 0, ret;  	if (!np)  		return -ENODEV; @@ -79,7 +78,7 @@ static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,  	adapter = of_find_i2c_adapter_by_node(adapter_np);  	if (!adapter) {  		dev_err(&pdev->dev, "Cannot find parent bus\n"); -		return -ENODEV; +		return -EPROBE_DEFER;  	}  	mux->data.parent = i2c_adapter_id(adapter);  	put_device(&adapter->dev); @@ -116,8 +115,12 @@ static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,  		return -ENOMEM;  	} -	for (i = 0; i < mux->data.n_gpios; i++) -		gpios[i] = of_get_named_gpio(np, "mux-gpios", i); +	for (i = 0; i < mux->data.n_gpios; i++) { +		ret = of_get_named_gpio(np, "mux-gpios", i); +		if (ret < 0) +			return ret; +		gpios[i] = ret; +	}  	mux->data.gpios = gpios; @@ -177,7 +180,7 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)  	if (!parent) {  		dev_err(&pdev->dev, "Parent adapter (%d) not found\n",  			mux->data.parent); -		return -ENODEV; +		return -EPROBE_DEFER;  	}  	mux->parent = parent; @@ -224,7 +227,7 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)  		unsigned int class = mux->data.classes ? mux->data.classes[i] : 0;  		mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr, -						   i, class, +						   mux->data.values[i], class,  						   i2c_mux_gpio_select, deselect);  		if (!mux->adap[i]) {  			ret = -ENODEV; @@ -279,7 +282,7 @@ static struct platform_driver i2c_mux_gpio_driver = {  	.driver	= {  		.owner	= THIS_MODULE,  		.name	= "i2c-mux-gpio", -		.of_match_table = of_match_ptr(i2c_mux_gpio_of_match), +		.of_match_table = i2c_mux_gpio_of_match,  	},  }; diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c index c4f08ad3118..cb772775da4 100644 --- a/drivers/i2c/muxes/i2c-mux-pca9541.c +++ b/drivers/i2c/muxes/i2c-mux-pca9541.c @@ -17,7 +17,6 @@   */  #include <linux/module.h> -#include <linux/init.h>  #include <linux/jiffies.h>  #include <linux/delay.h>  #include <linux/slab.h> diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c index bad5b84a598..9bd4212782a 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c @@ -28,21 +28,20 @@   * Based on:   *	i2c-virtual_cb.c from Brian Kuschak <bkuschak@yahoo.com>   * and - *	pca9540.c from Jean Delvare <khali@linux-fr.org>. + *	pca9540.c from Jean Delvare <jdelvare@suse.de>.   *   * 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 <linux/module.h> -#include <linux/init.h> -#include <linux/slab.h>  #include <linux/device.h> +#include <linux/gpio/consumer.h>  #include <linux/i2c.h>  #include <linux/i2c-mux.h> -  #include <linux/i2c/pca954x.h> +#include <linux/module.h> +#include <linux/slab.h>  #define PCA954X_MAX_NCHANS 8 @@ -186,28 +185,32 @@ static int pca954x_probe(struct i2c_client *client,  {  	struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);  	struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev); +	struct gpio_desc *gpio;  	int num, force, class;  	struct pca954x *data; -	int ret = -ENODEV; +	int ret;  	if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) -		goto err; +		return -ENODEV; -	data = kzalloc(sizeof(struct pca954x), GFP_KERNEL); -	if (!data) { -		ret = -ENOMEM; -		goto err; -	} +	data = devm_kzalloc(&client->dev, sizeof(struct pca954x), GFP_KERNEL); +	if (!data) +		return -ENOMEM;  	i2c_set_clientdata(client, data); +	/* Get the mux out of reset if a reset GPIO is specified. */ +	gpio = devm_gpiod_get(&client->dev, "reset"); +	if (!IS_ERR(gpio)) +		gpiod_direction_output(gpio, 0); +  	/* Write the mux register at addr to verify  	 * that the mux is in fact present. This also  	 * initializes the mux to disconnected state.  	 */  	if (i2c_smbus_write_byte(client, 0) < 0) {  		dev_warn(&client->dev, "probe failed\n"); -		goto exit_free; +		return -ENODEV;  	}  	data->type = id->driver_data; @@ -252,9 +255,6 @@ static int pca954x_probe(struct i2c_client *client,  virt_reg_failed:  	for (num--; num >= 0; num--)  		i2c_del_mux_adapter(data->virt_adaps[num]); -exit_free: -	kfree(data); -err:  	return ret;  } @@ -270,7 +270,6 @@ static int pca954x_remove(struct i2c_client *client)  			data->virt_adaps[i] = NULL;  		} -	kfree(data);  	return 0;  } diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c index 69a91732ae6..4ff0ef3e07a 100644 --- a/drivers/i2c/muxes/i2c-mux-pinctrl.c +++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c @@ -18,12 +18,12 @@  #include <linux/i2c.h>  #include <linux/i2c-mux.h> -#include <linux/init.h>  #include <linux/module.h>  #include <linux/pinctrl/consumer.h>  #include <linux/i2c-mux-pinctrl.h>  #include <linux/platform_device.h>  #include <linux/slab.h> +#include <linux/of.h>  struct i2c_mux_pinctrl {  	struct device *dev; @@ -113,7 +113,7 @@ static int i2c_mux_pinctrl_parse_dt(struct i2c_mux_pinctrl *mux,  	adapter = of_find_i2c_adapter_by_node(adapter_np);  	if (!adapter) {  		dev_err(mux->dev, "Cannot find parent bus\n"); -		return -ENODEV; +		return -EPROBE_DEFER;  	}  	mux->pdata->parent_bus_num = i2c_adapter_id(adapter);  	put_device(&adapter->dev); @@ -211,7 +211,7 @@ static int i2c_mux_pinctrl_probe(struct platform_device *pdev)  	if (!mux->parent) {  		dev_err(&pdev->dev, "Parent adapter (%d) not found\n",  			mux->pdata->parent_bus_num); -		ret = -ENODEV; +		ret = -EPROBE_DEFER;  		goto err;  	}  | 
