diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-08 11:31:16 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-08 11:31:16 -0700 |
commit | 3f17ea6dea8ba5668873afa54628a91aaa3fb1c0 (patch) | |
tree | afbeb2accd4c2199ddd705ae943995b143a0af02 /drivers/i2c/busses | |
parent | 1860e379875dfe7271c649058aeddffe5afd9d0d (diff) | |
parent | 1a5700bc2d10cd379a795fd2bb377a190af5acd4 (diff) |
Merge branch 'next' (accumulated 3.16 merge window patches) into master
Now that 3.15 is released, this merges the 'next' branch into 'master',
bringing us to the normal situation where my 'master' branch is the
merge window.
* accumulated work in next: (6809 commits)
ufs: sb mutex merge + mutex_destroy
powerpc: update comments for generic idle conversion
cris: update comments for generic idle conversion
idle: remove cpu_idle() forward declarations
nbd: zero from and len fields in NBD_CMD_DISCONNECT.
mm: convert some level-less printks to pr_*
MAINTAINERS: adi-buildroot-devel is moderated
MAINTAINERS: add linux-api for review of API/ABI changes
mm/kmemleak-test.c: use pr_fmt for logging
fs/dlm/debug_fs.c: replace seq_printf by seq_puts
fs/dlm/lockspace.c: convert simple_str to kstr
fs/dlm/config.c: convert simple_str to kstr
mm: mark remap_file_pages() syscall as deprecated
mm: memcontrol: remove unnecessary memcg argument from soft limit functions
mm: memcontrol: clean up memcg zoneinfo lookup
mm/memblock.c: call kmemleak directly from memblock_(alloc|free)
mm/mempool.c: update the kmemleak stack trace for mempool allocations
lib/radix-tree.c: update the kmemleak stack trace for radix tree allocations
mm: introduce kmemleak_update_trace()
mm/kmemleak.c: use %u to print ->checksum
...
Diffstat (limited to 'drivers/i2c/busses')
32 files changed, 769 insertions, 1262 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index c94db1c5e35..620d1004a1e 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -449,7 +449,7 @@ config I2C_EFM32 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. @@ -570,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 @@ -993,6 +986,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 18d18ff9db9..298692cc600 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -55,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 @@ -95,6 +94,7 @@ 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-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 98a1c97739b..15517d78d5f 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c @@ -63,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; @@ -78,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; @@ -102,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) { @@ -117,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; @@ -142,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; @@ -184,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]; @@ -198,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; @@ -208,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); @@ -224,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) { @@ -268,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; @@ -292,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)) @@ -317,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 | @@ -329,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; } @@ -350,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; } } @@ -375,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 = { @@ -394,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; @@ -421,12 +429,12 @@ static const struct pci_device_id ali1563_id_table[] = { {}, }; -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-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c index c60719577fc..214ff9700ef 100644 --- a/drivers/i2c/busses/i2c-bcm2835.c +++ b/drivers/i2c/busses/i2c-bcm2835.c @@ -225,10 +225,8 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) 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); diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index e6d5162b637..3e271e7558d 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c @@ -620,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; @@ -666,15 +658,15 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev) "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 */ @@ -695,7 +687,7 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev) 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); @@ -705,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: +out_error: peripheral_free_list(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: return rc; } @@ -724,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(dev_get_platdata(&pdev->dev)); - iounmap(iface->regs_base); - kfree(iface); return 0; } 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-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c index 85056c22d21..3356f7ab9f7 100644 --- a/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -56,6 +56,7 @@ enum dw_pci_ctl_id_t { medfield_5, baytrail, + haswell, }; struct dw_scl_sda_cfg { @@ -95,6 +96,15 @@ static struct dw_scl_sda_cfg byt_config = { .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, @@ -168,6 +178,15 @@ static struct dw_pci_controller dw_pci_controllers[] = { .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, @@ -328,6 +347,9 @@ static const struct pci_device_id i2_designware_pci_ids[] = { { 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 9c780261434..402ec3970fe 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -247,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; @@ -268,13 +269,11 @@ 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"); @@ -286,7 +285,7 @@ static struct platform_driver dw_i2c_driver = { .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, }, }; diff --git a/drivers/i2c/busses/i2c-diolan-u2c.c b/drivers/i2c/busses/i2c-diolan-u2c.c index 721f7ebf9a3..b19a310bf9b 100644 --- a/drivers/i2c/busses/i2c-diolan-u2c.c +++ b/drivers/i2c/busses/i2c-diolan-u2c.c @@ -455,7 +455,6 @@ static int diolan_u2c_probe(struct usb_interface *interface, /* 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; } diff --git a/drivers/i2c/busses/i2c-efm32.c b/drivers/i2c/busses/i2c-efm32.c index 777ed409a24..f7eccd682de 100644 --- a/drivers/i2c/busses/i2c-efm32.c +++ b/drivers/i2c/busses/i2c-efm32.c @@ -320,10 +320,8 @@ static int efm32_i2c_probe(struct platform_device *pdev) return -EINVAL; ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL); - if (!ddata) { - dev_dbg(&pdev->dev, "failed to allocate private data\n"); + if (!ddata) return -ENOMEM; - } platform_set_drvdata(pdev, ddata); init_completion(&ddata->done); diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index ff775ac29e4..a44ea13d143 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c @@ -751,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 index 00af0a0a336..63d22920285 100644 --- a/drivers/i2c/busses/i2c-exynos5.c +++ b/drivers/i2c/busses/i2c-exynos5.c @@ -76,12 +76,6 @@ #define HSI2C_RXFIFO_TRIGGER_LEVEL(x) ((x) << 4) #define HSI2C_TXFIFO_TRIGGER_LEVEL(x) ((x) << 16) -/* As per user manual FIFO max depth is 64bytes */ -#define HSI2C_FIFO_MAX 0x40 -/* default trigger levels for Tx and Rx FIFOs */ -#define HSI2C_DEF_TXFIFO_LVL (HSI2C_FIFO_MAX - 0x30) -#define HSI2C_DEF_RXFIFO_LVL (HSI2C_FIFO_MAX - 0x10) - /* I2C_TRAILING_CTL Register bits */ #define HSI2C_TRAILING_COUNT (0xf) @@ -183,14 +177,54 @@ struct exynos5_i2c { * 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" }, - {}, + { + .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), @@ -415,7 +449,7 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id) fifo_status = readl(i2c->regs + HSI2C_FIFO_STATUS); fifo_level = HSI2C_TX_FIFO_LVL(fifo_status); - len = HSI2C_FIFO_MAX - fifo_level; + len = i2c->variant->fifo_depth - fifo_level; if (len > (i2c->msg->len - i2c->msg_ptr)) len = i2c->msg->len - i2c->msg_ptr; @@ -483,6 +517,7 @@ static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop) 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); @@ -493,13 +528,19 @@ static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop) i2c_auto_conf = HSI2C_READ_WRITE; - fifo_ctl |= HSI2C_RXFIFO_TRIGGER_LEVEL(HSI2C_DEF_TXFIFO_LVL); + 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; - fifo_ctl |= HSI2C_TXFIFO_TRIGGER_LEVEL(HSI2C_DEF_RXFIFO_LVL); + 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; } @@ -621,10 +662,8 @@ static int exynos5_i2c_probe(struct platform_device *pdev) int ret; i2c = devm_kzalloc(&pdev->dev, sizeof(struct exynos5_i2c), GFP_KERNEL); - if (!i2c) { - dev_err(&pdev->dev, "no memory for state\n"); + if (!i2c) return -ENOMEM; - } if (of_property_read_u32(np, "clock-frequency", &op_clock)) { i2c->speed_mode = HSI2C_FAST_SPD; @@ -691,7 +730,9 @@ static int exynos5_i2c_probe(struct platform_device *pdev) if (ret) goto err_clk; - exynos5_i2c_init(i2c); + i2c->variant = exynos5_i2c_get_variant(pdev); + + exynos5_i2c_reset(i2c); ret = i2c_add_adapter(&i2c->adap); if (ret < 0) { diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c index 02d2d4abb9d..71a45b210a2 100644 --- a/drivers/i2c/busses/i2c-gpio.c +++ b/drivers/i2c/busses/i2c-gpio.c @@ -147,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; @@ -225,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); @@ -235,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) @@ -255,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-imx.c b/drivers/i2c/busses/i2c-imx.c index db895fb22e6..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,6 +356,8 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx) dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); + i2c_imx_set_clk(i2c_imx); + result = clk_prepare_enable(i2c_imx->clk); if (result) return result; @@ -367,45 +413,6 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx) clk_disable_unprepare(i2c_imx->clk); } -static void 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; @@ -458,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", @@ -481,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 */ @@ -490,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__); @@ -510,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]); @@ -523,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__); @@ -534,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__); @@ -564,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) @@ -583,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 = { @@ -600,7 +651,6 @@ static int 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__); @@ -617,10 +667,8 @@ static int 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; @@ -664,12 +712,11 @@ static int 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, diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index f5391633b53..6a32aa095f8 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -115,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 540ea692bf7..9f4b775e2e3 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -681,7 +681,7 @@ 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}, diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index 32c85e9ecda..0e55d85fd4e 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c @@ -879,19 +879,19 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg) #ifdef CONFIG_PM_SLEEP static int nmk_i2c_suspend_late(struct device *dev) { - pinctrl_pm_select_sleep_state(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) { - /* First go to the default state */ - 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; + return pm_runtime_force_resume(dev); } #endif 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 1f6369f14fb..0e10cc6182f 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -250,7 +250,7 @@ static struct i2c_adapter ocores_adapter = { .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-omap.c b/drivers/i2c/busses/i2c-omap.c index 85f8eac9ba1..b182793a405 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1114,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); 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-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 06d47aafbb7..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,16 +14,12 @@ * * 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> @@ -36,7 +34,6 @@ #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) @@ -112,14 +95,12 @@ struct rcar_i2c_priv { 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) @@ -130,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); @@ -161,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; @@ -205,24 +154,6 @@ 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) @@ -312,60 +243,18 @@ scgd_find: 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); - - 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; + int read = !!rcar_i2c_is_recv(priv); - /* - * It should check bus status when send case - */ - ret = rcar_i2c_bus_barrier(priv); - if (ret < 0) - return ret; - - 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 */ @@ -386,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) { /* @@ -414,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, @@ -425,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; } @@ -462,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; } @@ -474,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 @@ -528,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; } @@ -545,21 +409,18 @@ 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++) { /* This HW can't send STOP after address phase */ if (msgs[i].len == 0) { @@ -567,9 +428,6 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, break; } - /*-------------- spin lock -----------------*/ - spin_lock_irqsave(&priv->lock, flags); - /* init each data */ priv->msg = &msgs[i]; priv->pos = 0; @@ -577,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); @@ -600,9 +448,6 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, break; } - /* - * error handling - */ if (rcar_i2c_flags_has(priv, ID_NACK)) { ret = -ENXIO; break; @@ -620,7 +465,7 @@ 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 && ret != -ENXIO) @@ -646,6 +491,9 @@ static const struct of_device_id rcar_i2c_dt_ids[] = { { .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); @@ -658,13 +506,11 @@ 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)) { @@ -692,9 +538,8 @@ 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; @@ -706,10 +551,10 @@ static int rcar_i2c_probe(struct platform_device *pdev) 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; } @@ -759,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 index 9e1f8bacfb3..af3b3d032a9 100644 --- a/drivers/i2c/busses/i2c-riic.c +++ b/drivers/i2c/busses/i2c-riic.c @@ -404,7 +404,7 @@ static int riic_i2c_remove(struct platform_device *pdev) return 0; } -static struct of_device_id riic_i2c_dt_ids[] = { +static const struct of_device_id riic_i2c_dt_ids[] = { { .compatible = "renesas,riic-rz" }, { /* Sentinel */ }, }; diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index bb3a9964f7e..e828a1dba0e 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -1114,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) diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 1d79585ba4b..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,52 +230,58 @@ 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_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_unprepare(pd->clk); + return 0; } static void activate_ch(struct sh_mobile_i2c_data *pd) @@ -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 294c80f21d6..964e5c6f84a 100644 --- a/drivers/i2c/busses/i2c-simtec.c +++ b/drivers/i2c/busses/i2c-simtec.c @@ -77,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 8e3be7ed058..a3216defc1d 100644 --- a/drivers/i2c/busses/i2c-sirf.c +++ b/drivers/i2c/busses/i2c-sirf.c @@ -307,7 +307,6 @@ 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; } diff --git a/drivers/i2c/busses/i2c-st.c b/drivers/i2c/busses/i2c-st.c index 872016196ef..95b94767038 100644 --- a/drivers/i2c/busses/i2c-st.c +++ b/drivers/i2c/busses/i2c-st.c @@ -847,7 +847,7 @@ static int st_i2c_remove(struct platform_device *pdev) return 0; } -static struct of_device_id st_i2c_match[] = { +static const struct of_device_id st_i2c_match[] = { { .compatible = "st,comms-ssc-i2c", }, { .compatible = "st,comms-ssc4-i2c", }, {}, diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c index 29b1fb77894..fefb1c19ec1 100644 --- a/drivers/i2c/busses/i2c-stu300.c +++ b/drivers/i2c/busses/i2c-stu300.c @@ -868,10 +868,8 @@ static int 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); diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 00f04cb5b4e..f1bb2fc0679 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -732,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; diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c index 2c8a3e4f900..f80a38c2072 100644 --- a/drivers/i2c/busses/i2c-wmt.c +++ b/drivers/i2c/busses/i2c-wmt.c @@ -379,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); @@ -454,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/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index cb66f9586f7..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); |