Merge branch 'i2c/for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c updates from Wolfram Sang:

 - new driver for ICY, an Amiga Zorro card :)

 - axxia driver gained slave mode support, NXP driver gained ACPI

 - the slave EEPROM backend gained 16 bit address support

 - and lots of regular driver updates and reworks

* 'i2c/for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (52 commits)
  i2c: tegra: Move suspend handling to NOIRQ phase
  i2c: imx: ACPI support for NXP i2c controller
  i2c: uniphier(-f): remove all dev_dbg()
  i2c: uniphier(-f): use devm_platform_ioremap_resource()
  i2c: slave-eeprom: Add comment about address handling
  i2c: exynos5: Remove IRQF_ONESHOT
  i2c: stm32f7: Make structure stm32f7_i2c_algo constant
  i2c: cht-wc: drop check because i2c_unregister_device() is NULL safe
  i2c-eeprom_slave: Add support for more eeprom models
  i2c: fsi: Add of_put_node() before break
  i2c: synquacer: Make synquacer_i2c_ops constant
  i2c: hix5hd2: Remove IRQF_ONESHOT
  i2c: i801: Use iTCO version 6 in Cannon Lake PCH and beyond
  watchdog: iTCO: Add support for Cannon Lake PCH iTCO
  i2c: iproc: Make bcm_iproc_i2c_quirks constant
  i2c: iproc: Add full name of devicetree node to adapter name
  i2c: piix4: Add ACPI support
  i2c: piix4: Fix probing of reserved ports on AMD Family 16h Model 30h
  i2c: ocores: use request_any_context_irq() to register IRQ handler
  i2c: designware: Fix optional reset error handling
  ...
This commit is contained in:
Linus Torvalds 2019-09-24 16:48:02 -07:00
commit 351c8a09b0
42 changed files with 795 additions and 267 deletions

View File

@ -1,7 +1,9 @@
Broadcom BCM2835 I2C controller
Required properties:
- compatible : Should be "brcm,bcm2835-i2c".
- compatible : Should be one of:
"brcm,bcm2711-i2c"
"brcm,bcm2835-i2c"
- reg: Should contain register location and length.
- interrupts: Should contain interrupt.
- clocks : The clock feeding the I2C controller.

View File

@ -7865,6 +7865,12 @@ S: Maintained
F: drivers/mfd/lpc_ich.c
F: drivers/gpio/gpio-ich.c
ICY I2C DRIVER
M: Max Staudt <max@enpas.org>
L: linux-i2c@vger.kernel.org
S: Maintained
F: drivers/i2c/busses/i2c-icy.c
IDE SUBSYSTEM
M: "David S. Miller" <davem@davemloft.net>
L: linux-ide@vger.kernel.org
@ -13791,7 +13797,7 @@ F: drivers/clk/renesas/
RENESAS EMEV2 I2C DRIVER
M: Wolfram Sang <wsa+renesas@sang-engineering.com>
S: Supported
F: Documentation/devicetree/bindings/i2c/i2c-emev2.txt
F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.txt
F: drivers/i2c/busses/i2c-emev2.c
RENESAS ETHERNET DRIVERS
@ -13813,15 +13819,15 @@ F: drivers/iio/adc/rcar-gyroadc.c
RENESAS R-CAR I2C DRIVERS
M: Wolfram Sang <wsa+renesas@sang-engineering.com>
S: Supported
F: Documentation/devicetree/bindings/i2c/i2c-rcar.txt
F: Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt
F: Documentation/devicetree/bindings/i2c/renesas,i2c.txt
F: Documentation/devicetree/bindings/i2c/renesas,iic.txt
F: drivers/i2c/busses/i2c-rcar.c
F: drivers/i2c/busses/i2c-sh_mobile.c
RENESAS RIIC DRIVER
M: Chris Brandt <chris.brandt@renesas.com>
S: Supported
F: Documentation/devicetree/bindings/i2c/i2c-riic.txt
F: Documentation/devicetree/bindings/i2c/renesas,riic.txt
F: drivers/i2c/busses/i2c-riic.c
RENESAS USB PHY DRIVER

View File

@ -160,11 +160,17 @@ static const struct apd_device_desc hip08_i2c_desc = {
.setup = acpi_apd_setup,
.fixed_clk_rate = 250000000,
};
static const struct apd_device_desc thunderx2_i2c_desc = {
.setup = acpi_apd_setup,
.fixed_clk_rate = 125000000,
};
static const struct apd_device_desc nxp_i2c_desc = {
.setup = acpi_apd_setup,
.fixed_clk_rate = 350000000,
};
static const struct apd_device_desc hip08_spi_desc = {
.setup = acpi_apd_setup,
.fixed_clk_rate = 250000000,
@ -238,6 +244,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = {
{ "HISI02A1", APD_ADDR(hip07_i2c_desc) },
{ "HISI02A2", APD_ADDR(hip08_i2c_desc) },
{ "HISI0173", APD_ADDR(hip08_spi_desc) },
{ "NXP0001", APD_ADDR(nxp_i2c_desc) },
#endif
{ }
};

View File

@ -978,10 +978,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv)
{
int ret;
adv->i2c_cec = i2c_new_secondary_device(adv->i2c_main, "cec",
adv->i2c_cec = i2c_new_ancillary_device(adv->i2c_main, "cec",
ADV7511_CEC_I2C_ADDR_DEFAULT);
if (!adv->i2c_cec)
return -EINVAL;
if (IS_ERR(adv->i2c_cec))
return PTR_ERR(adv->i2c_cec);
i2c_set_clientdata(adv->i2c_cec, adv);
adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec,
@ -1162,20 +1162,20 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
adv7511_packet_disable(adv7511, 0xffff);
adv7511->i2c_edid = i2c_new_secondary_device(i2c, "edid",
adv7511->i2c_edid = i2c_new_ancillary_device(i2c, "edid",
ADV7511_EDID_I2C_ADDR_DEFAULT);
if (!adv7511->i2c_edid) {
ret = -EINVAL;
if (IS_ERR(adv7511->i2c_edid)) {
ret = PTR_ERR(adv7511->i2c_edid);
goto uninit_regulators;
}
regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR,
adv7511->i2c_edid->addr << 1);
adv7511->i2c_packet = i2c_new_secondary_device(i2c, "packet",
adv7511->i2c_packet = i2c_new_ancillary_device(i2c, "packet",
ADV7511_PACKET_I2C_ADDR_DEFAULT);
if (!adv7511->i2c_packet) {
ret = -EINVAL;
if (IS_ERR(adv7511->i2c_packet)) {
ret = PTR_ERR(adv7511->i2c_packet);
goto err_i2c_unregister_edid;
}

View File

@ -429,6 +429,7 @@ config I2C_AXXIA
tristate "Axxia I2C controller"
depends on ARCH_AXXIA || COMPILE_TEST
default ARCH_AXXIA
select I2C_SLAVE
help
Say yes if you want to support the I2C bus on Axxia platforms.
@ -977,7 +978,7 @@ config I2C_SIRF
will be called i2c-sirf.
config I2C_SPRD
bool "Spreadtrum I2C interface"
tristate "Spreadtrum I2C interface"
depends on I2C=y && ARCH_SPRD
help
If you say yes to this option, support will be included for the
@ -1309,6 +1310,20 @@ config I2C_ELEKTOR
This support is also available as a module. If so, the module
will be called i2c-elektor.
config I2C_ICY
tristate "ICY Zorro card"
depends on ZORRO
select I2C_ALGOPCF
help
This supports the PCF8584 Zorro bus I2C adapter, known as ICY.
Say Y if you own such an adapter.
This support is also available as a module. If so, the module
will be called i2c-icy.
If you have a 2019 edition board with an LTC2990 sensor at address
0x4c, loading the module 'ltc2990' is sufficient to enable it.
config I2C_MLXCPLD
tristate "Mellanox I2C driver"
depends on X86_64

View File

@ -140,6 +140,7 @@ obj-$(CONFIG_I2C_BCM_KONA) += i2c-bcm-kona.o
obj-$(CONFIG_I2C_BRCMSTB) += i2c-brcmstb.o
obj-$(CONFIG_I2C_CROS_EC_TUNNEL) += i2c-cros-ec-tunnel.o
obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
obj-$(CONFIG_I2C_ICY) += i2c-icy.o
obj-$(CONFIG_I2C_MLXCPLD) += i2c-mlxcpld.o
obj-$(CONFIG_I2C_OPAL) += i2c-opal.o
obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o

View File

@ -77,6 +77,40 @@
MST_STATUS_IP)
#define MST_TX_BYTES_XFRD 0x50
#define MST_RX_BYTES_XFRD 0x54
#define SLV_ADDR_DEC_CTL 0x58
#define SLV_ADDR_DEC_GCE BIT(0) /* ACK to General Call Address from own master (loopback) */
#define SLV_ADDR_DEC_OGCE BIT(1) /* ACK to General Call Address from external masters */
#define SLV_ADDR_DEC_SA1E BIT(2) /* ACK to addr_1 enabled */
#define SLV_ADDR_DEC_SA1M BIT(3) /* 10-bit addressing for addr_1 enabled */
#define SLV_ADDR_DEC_SA2E BIT(4) /* ACK to addr_2 enabled */
#define SLV_ADDR_DEC_SA2M BIT(5) /* 10-bit addressing for addr_2 enabled */
#define SLV_ADDR_1 0x5c
#define SLV_ADDR_2 0x60
#define SLV_RX_CTL 0x64
#define SLV_RX_ACSA1 BIT(0) /* Generate ACK for writes to addr_1 */
#define SLV_RX_ACSA2 BIT(1) /* Generate ACK for writes to addr_2 */
#define SLV_RX_ACGCA BIT(2) /* ACK data phase transfers to General Call Address */
#define SLV_DATA 0x68
#define SLV_RX_FIFO 0x6c
#define SLV_FIFO_DV1 BIT(0) /* Data Valid for addr_1 */
#define SLV_FIFO_DV2 BIT(1) /* Data Valid for addr_2 */
#define SLV_FIFO_AS BIT(2) /* (N)ACK Sent */
#define SLV_FIFO_TNAK BIT(3) /* Timeout NACK */
#define SLV_FIFO_STRC BIT(4) /* First byte after start condition received */
#define SLV_FIFO_RSC BIT(5) /* Repeated Start Condition */
#define SLV_FIFO_STPC BIT(6) /* Stop Condition */
#define SLV_FIFO_DV (SLV_FIFO_DV1 | SLV_FIFO_DV2)
#define SLV_INT_ENABLE 0x70
#define SLV_INT_STATUS 0x74
#define SLV_STATUS_RFH BIT(0) /* FIFO service */
#define SLV_STATUS_WTC BIT(1) /* Write transfer complete */
#define SLV_STATUS_SRS1 BIT(2) /* Slave read from addr 1 */
#define SLV_STATUS_SRRS1 BIT(3) /* Repeated start from addr 1 */
#define SLV_STATUS_SRND1 BIT(4) /* Read request not following start condition */
#define SLV_STATUS_SRC1 BIT(5) /* Read canceled */
#define SLV_STATUS_SRAT1 BIT(6) /* Slave Read timed out */
#define SLV_STATUS_SRDRE1 BIT(7) /* Data written after timed out */
#define SLV_READ_DUMMY 0x78
#define SCL_HIGH_PERIOD 0x80
#define SCL_LOW_PERIOD 0x84
#define SPIKE_FLTR_LEN 0x88
@ -111,6 +145,8 @@ struct axxia_i2c_dev {
struct clk *i2c_clk;
u32 bus_clk_rate;
bool last;
struct i2c_client *slave;
int irq;
};
static void i2c_int_disable(struct axxia_i2c_dev *idev, u32 mask)
@ -276,13 +312,65 @@ static int axxia_i2c_fill_tx_fifo(struct axxia_i2c_dev *idev)
return ret;
}
static void axxia_i2c_slv_fifo_event(struct axxia_i2c_dev *idev)
{
u32 fifo_status = readl(idev->base + SLV_RX_FIFO);
u8 val;
dev_dbg(idev->dev, "slave irq fifo_status=0x%x\n", fifo_status);
if (fifo_status & SLV_FIFO_DV1) {
if (fifo_status & SLV_FIFO_STRC)
i2c_slave_event(idev->slave,
I2C_SLAVE_WRITE_REQUESTED, &val);
val = readl(idev->base + SLV_DATA);
i2c_slave_event(idev->slave, I2C_SLAVE_WRITE_RECEIVED, &val);
}
if (fifo_status & SLV_FIFO_STPC) {
readl(idev->base + SLV_DATA); /* dummy read */
i2c_slave_event(idev->slave, I2C_SLAVE_STOP, &val);
}
if (fifo_status & SLV_FIFO_RSC)
readl(idev->base + SLV_DATA); /* dummy read */
}
static irqreturn_t axxia_i2c_slv_isr(struct axxia_i2c_dev *idev)
{
u32 status = readl(idev->base + SLV_INT_STATUS);
u8 val;
dev_dbg(idev->dev, "slave irq status=0x%x\n", status);
if (status & SLV_STATUS_RFH)
axxia_i2c_slv_fifo_event(idev);
if (status & SLV_STATUS_SRS1) {
i2c_slave_event(idev->slave, I2C_SLAVE_READ_REQUESTED, &val);
writel(val, idev->base + SLV_DATA);
}
if (status & SLV_STATUS_SRND1) {
i2c_slave_event(idev->slave, I2C_SLAVE_READ_PROCESSED, &val);
writel(val, idev->base + SLV_DATA);
}
if (status & SLV_STATUS_SRC1)
i2c_slave_event(idev->slave, I2C_SLAVE_STOP, &val);
writel(INT_SLV, idev->base + INTERRUPT_STATUS);
return IRQ_HANDLED;
}
static irqreturn_t axxia_i2c_isr(int irq, void *_dev)
{
struct axxia_i2c_dev *idev = _dev;
irqreturn_t ret = IRQ_NONE;
u32 status;
if (!(readl(idev->base + INTERRUPT_STATUS) & INT_MST))
return IRQ_NONE;
status = readl(idev->base + INTERRUPT_STATUS);
if (status & INT_SLV)
ret = axxia_i2c_slv_isr(idev);
if (!(status & INT_MST))
return ret;
/* Read interrupt status bits */
status = readl(idev->base + MST_INT_STATUS);
@ -583,9 +671,58 @@ static u32 axxia_i2c_func(struct i2c_adapter *adap)
return caps;
}
static int axxia_i2c_reg_slave(struct i2c_client *slave)
{
struct axxia_i2c_dev *idev = i2c_get_adapdata(slave->adapter);
u32 slv_int_mask = SLV_STATUS_RFH;
u32 dec_ctl;
if (idev->slave)
return -EBUSY;
idev->slave = slave;
/* Enable slave mode as well */
writel(GLOBAL_MST_EN | GLOBAL_SLV_EN, idev->base + GLOBAL_CONTROL);
writel(INT_MST | INT_SLV, idev->base + INTERRUPT_ENABLE);
/* Set slave address */
dec_ctl = SLV_ADDR_DEC_SA1E;
if (slave->flags & I2C_CLIENT_TEN)
dec_ctl |= SLV_ADDR_DEC_SA1M;
writel(SLV_RX_ACSA1, idev->base + SLV_RX_CTL);
writel(dec_ctl, idev->base + SLV_ADDR_DEC_CTL);
writel(slave->addr, idev->base + SLV_ADDR_1);
/* Enable interrupts */
slv_int_mask |= SLV_STATUS_SRS1 | SLV_STATUS_SRRS1 | SLV_STATUS_SRND1;
slv_int_mask |= SLV_STATUS_SRC1;
writel(slv_int_mask, idev->base + SLV_INT_ENABLE);
return 0;
}
static int axxia_i2c_unreg_slave(struct i2c_client *slave)
{
struct axxia_i2c_dev *idev = i2c_get_adapdata(slave->adapter);
/* Disable slave mode */
writel(GLOBAL_MST_EN, idev->base + GLOBAL_CONTROL);
writel(INT_MST, idev->base + INTERRUPT_ENABLE);
synchronize_irq(idev->irq);
idev->slave = NULL;
return 0;
}
static const struct i2c_algorithm axxia_i2c_algo = {
.master_xfer = axxia_i2c_xfer,
.functionality = axxia_i2c_func,
.reg_slave = axxia_i2c_reg_slave,
.unreg_slave = axxia_i2c_unreg_slave,
};
static const struct i2c_adapter_quirks axxia_i2c_quirks = {
@ -599,7 +736,6 @@ static int axxia_i2c_probe(struct platform_device *pdev)
struct axxia_i2c_dev *idev = NULL;
struct resource *res;
void __iomem *base;
int irq;
int ret = 0;
idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL);
@ -611,10 +747,10 @@ static int axxia_i2c_probe(struct platform_device *pdev)
if (IS_ERR(base))
return PTR_ERR(base);
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
idev->irq = platform_get_irq(pdev, 0);
if (idev->irq < 0) {
dev_err(&pdev->dev, "missing interrupt resource\n");
return irq;
return idev->irq;
}
idev->i2c_clk = devm_clk_get(&pdev->dev, "i2c");
@ -643,10 +779,10 @@ static int axxia_i2c_probe(struct platform_device *pdev)
goto error_disable_clk;
}
ret = devm_request_irq(&pdev->dev, irq, axxia_i2c_isr, 0,
ret = devm_request_irq(&pdev->dev, idev->irq, axxia_i2c_isr, 0,
pdev->name, idev);
if (ret) {
dev_err(&pdev->dev, "failed to claim IRQ%d\n", irq);
dev_err(&pdev->dev, "failed to claim IRQ%d\n", idev->irq);
goto error_disable_clk;
}

View File

@ -808,7 +808,7 @@ static struct i2c_algorithm bcm_iproc_algo = {
.unreg_slave = bcm_iproc_i2c_unreg_slave,
};
static struct i2c_adapter_quirks bcm_iproc_i2c_quirks = {
static const struct i2c_adapter_quirks bcm_iproc_i2c_quirks = {
.max_read_len = M_RX_MAX_READ_LEN,
};
@ -922,7 +922,9 @@ static int bcm_iproc_i2c_probe(struct platform_device *pdev)
adap = &iproc_i2c->adapter;
i2c_set_adapdata(adap, iproc_i2c);
strlcpy(adap->name, "Broadcom iProc I2C adapter", sizeof(adap->name));
snprintf(adap->name, sizeof(adap->name),
"Broadcom iProc (%s)",
of_node_full_name(iproc_i2c->device->of_node));
adap->algo = &bcm_iproc_algo;
adap->quirks = &bcm_iproc_i2c_quirks;
adap->dev.parent = &pdev->dev;

View File

@ -12,6 +12,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
@ -389,7 +390,7 @@ static const struct i2c_algorithm bcm2835_i2c_algo = {
};
/*
* This HW was reported to have problems with clock stretching:
* The BCM2835 was reported to have problems with clock stretching:
* http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html
* https://www.raspberrypi.org/forums/viewtopic.php?p=146272
*/
@ -471,11 +472,12 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
i2c_set_adapdata(adap, i2c_dev);
adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_DEPRECATED;
strlcpy(adap->name, "bcm2835 I2C adapter", sizeof(adap->name));
snprintf(adap->name, sizeof(adap->name), "bcm2835 (%s)",
of_node_full_name(pdev->dev.of_node));
adap->algo = &bcm2835_i2c_algo;
adap->dev.parent = &pdev->dev;
adap->dev.of_node = pdev->dev.of_node;
adap->quirks = &bcm2835_i2c_quirks;
adap->quirks = of_device_get_match_data(&pdev->dev);
bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 0);
@ -501,7 +503,8 @@ static int bcm2835_i2c_remove(struct platform_device *pdev)
}
static const struct of_device_id bcm2835_i2c_of_match[] = {
{ .compatible = "brcm,bcm2835-i2c" },
{ .compatible = "brcm,bcm2711-i2c" },
{ .compatible = "brcm,bcm2835-i2c", .data = &bcm2835_i2c_quirks },
{},
};
MODULE_DEVICE_TABLE(of, bcm2835_i2c_of_match);

View File

@ -178,6 +178,51 @@ static const struct i2c_algorithm cht_wc_i2c_adap_algo = {
.smbus_xfer = cht_wc_i2c_adap_smbus_xfer,
};
/*
* We are an i2c-adapter which itself is part of an i2c-client. This means that
* transfers done through us take adapter->bus_lock twice, once for our parent
* i2c-adapter and once to take our own bus_lock. Lockdep does not like this
* nested locking, to make lockdep happy in the case of busses with muxes, the
* i2c-core's i2c_adapter_lock_bus function calls:
* rt_mutex_lock_nested(&adapter->bus_lock, i2c_adapter_depth(adapter));
*
* But i2c_adapter_depth only works when the direct parent of the adapter is
* another adapter, as it is only meant for muxes. In our case there is an
* i2c-client and MFD instantiated platform_device in the parent->child chain
* between the 2 devices.
*
* So we override the default i2c_lock_operations and pass a hardcoded
* depth of 1 to rt_mutex_lock_nested, to make lockdep happy.
*
* Note that if there were to be a mux attached to our adapter, this would
* break things again since the i2c-mux code expects the root-adapter to have
* a locking depth of 0. But we always have only 1 client directly attached
* in the form of the Charger IC paired with the CHT Whiskey Cove PMIC.
*/
static void cht_wc_i2c_adap_lock_bus(struct i2c_adapter *adapter,
unsigned int flags)
{
rt_mutex_lock_nested(&adapter->bus_lock, 1);
}
static int cht_wc_i2c_adap_trylock_bus(struct i2c_adapter *adapter,
unsigned int flags)
{
return rt_mutex_trylock(&adapter->bus_lock);
}
static void cht_wc_i2c_adap_unlock_bus(struct i2c_adapter *adapter,
unsigned int flags)
{
rt_mutex_unlock(&adapter->bus_lock);
}
static const struct i2c_lock_operations cht_wc_i2c_adap_lock_ops = {
.lock_bus = cht_wc_i2c_adap_lock_bus,
.trylock_bus = cht_wc_i2c_adap_trylock_bus,
.unlock_bus = cht_wc_i2c_adap_unlock_bus,
};
/**** irqchip for the client connected to the extchgr i2c adapter ****/
static void cht_wc_i2c_irq_lock(struct irq_data *data)
{
@ -286,6 +331,7 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
adap->adapter.owner = THIS_MODULE;
adap->adapter.class = I2C_CLASS_HWMON;
adap->adapter.algo = &cht_wc_i2c_adap_algo;
adap->adapter.lock_ops = &cht_wc_i2c_adap_lock_ops;
strlcpy(adap->adapter.name, "PMIC I2C Adapter",
sizeof(adap->adapter.name));
adap->adapter.dev.parent = &pdev->dev;
@ -363,7 +409,6 @@ static int cht_wc_i2c_adap_i2c_remove(struct platform_device *pdev)
{
struct cht_wc_i2c_adap *adap = platform_get_drvdata(pdev);
if (adap->client)
i2c_unregister_device(adap->client);
i2c_del_adapter(&adap->adapter);
irq_domain_remove(adap->irq_domain);

View File

@ -655,15 +655,11 @@ static int i2c_dw_init_recovery_info(struct dw_i2c_dev *dev)
struct i2c_bus_recovery_info *rinfo = &dev->rinfo;
struct i2c_adapter *adap = &dev->adapter;
struct gpio_desc *gpio;
int r;
gpio = devm_gpiod_get(dev->dev, "scl", GPIOD_OUT_HIGH);
if (IS_ERR(gpio)) {
r = PTR_ERR(gpio);
if (r == -ENOENT || r == -ENOSYS)
return 0;
return r;
}
gpio = devm_gpiod_get_optional(dev->dev, "scl", GPIOD_OUT_HIGH);
if (IS_ERR_OR_NULL(gpio))
return PTR_ERR_OR_ZERO(gpio);
rinfo->scl_gpiod = gpio;
gpio = devm_gpiod_get_optional(dev->dev, "sda", GPIOD_IN);

View File

@ -33,6 +33,7 @@ enum dw_pci_ctl_id_t {
baytrail,
cherrytrail,
haswell,
elkhartlake,
};
struct dw_scl_sda_cfg {
@ -168,13 +169,20 @@ static struct dw_pci_controller dw_pci_controllers[] = {
.flags = MODEL_CHERRYTRAIL,
.scl_sda_cfg = &byt_config,
},
[elkhartlake] = {
.bus_num = -1,
.bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
.tx_fifo_depth = 32,
.rx_fifo_depth = 32,
.functionality = I2C_FUNC_10BIT_ADDR,
.clk_khz = 100000,
},
};
#ifdef CONFIG_PM
static int i2c_dw_pci_suspend(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct dw_i2c_dev *i_dev = pci_get_drvdata(pdev);
struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
i_dev->suspended = true;
i_dev->disable(i_dev);
@ -184,8 +192,7 @@ static int i2c_dw_pci_suspend(struct device *dev)
static int i2c_dw_pci_resume(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct dw_i2c_dev *i_dev = pci_get_drvdata(pdev);
struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
int ret;
ret = i_dev->init(i_dev);
@ -227,6 +234,8 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
return r;
}
pci_set_master(pdev);
r = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
if (r) {
dev_err(&pdev->dev, "I/O memory remapping failed\n");
@ -237,19 +246,25 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
if (!dev)
return -ENOMEM;
r = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
if (r < 0)
return r;
dev->clk = NULL;
dev->controller = controller;
dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
dev->base = pcim_iomap_table(pdev)[0];
dev->dev = &pdev->dev;
dev->irq = pdev->irq;
dev->irq = pci_irq_vector(pdev, 0);
dev->flags |= controller->flags;
if (controller->setup) {
r = controller->setup(pdev, controller);
if (r)
if (r) {
pci_free_irq_vectors(pdev);
return r;
}
}
dev->functionality = controller->functionality |
DW_IC_DEFAULT_FUNCTIONALITY;
@ -276,8 +291,10 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
adap->nr = controller->bus_num;
r = i2c_dw_probe(dev);
if (r)
if (r) {
pci_free_irq_vectors(pdev);
return r;
}
pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
pm_runtime_use_autosuspend(&pdev->dev);
@ -296,6 +313,7 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev)
pm_runtime_get_noresume(&pdev->dev);
i2c_del_adapter(&dev->adapter);
pci_free_irq_vectors(pdev);
}
/* work with hotplug and coldplug */
@ -331,6 +349,15 @@ static const struct pci_device_id i2_designware_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x22C5), cherrytrail },
{ PCI_VDEVICE(INTEL, 0x22C6), cherrytrail },
{ PCI_VDEVICE(INTEL, 0x22C7), cherrytrail },
/* Elkhart Lake (PSE I2C) */
{ PCI_VDEVICE(INTEL, 0x4bb9), elkhartlake },
{ PCI_VDEVICE(INTEL, 0x4bba), elkhartlake },
{ PCI_VDEVICE(INTEL, 0x4bbb), elkhartlake },
{ PCI_VDEVICE(INTEL, 0x4bbc), elkhartlake },
{ PCI_VDEVICE(INTEL, 0x4bbd), elkhartlake },
{ PCI_VDEVICE(INTEL, 0x4bbe), elkhartlake },
{ PCI_VDEVICE(INTEL, 0x4bbf), elkhartlake },
{ PCI_VDEVICE(INTEL, 0x4bc0), elkhartlake },
{ 0,}
};
MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids);

View File

@ -279,12 +279,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, dev);
dev->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
if (IS_ERR(dev->rst)) {
if (PTR_ERR(dev->rst) == -EPROBE_DEFER)
return -EPROBE_DEFER;
} else {
if (IS_ERR(dev->rst))
return PTR_ERR(dev->rst);
reset_control_deassert(dev->rst);
}
t = &dev->timings;
if (pdata)
@ -346,8 +344,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
/* Optional interface clock */
dev->pclk = devm_clk_get_optional(&pdev->dev, "pclk");
if (IS_ERR(dev->pclk))
return PTR_ERR(dev->pclk);
if (IS_ERR(dev->pclk)) {
ret = PTR_ERR(dev->pclk);
goto exit_reset;
}
dev->clk = devm_clk_get(&pdev->dev, NULL);
if (!i2c_dw_prepare_clk(dev, true)) {
@ -400,7 +400,6 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
exit_probe:
dw_i2c_plat_pm_cleanup(dev);
exit_reset:
if (!IS_ERR_OR_NULL(dev->rst))
reset_control_assert(dev->rst);
return ret;
}
@ -419,7 +418,6 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
pm_runtime_put_sync(&pdev->dev);
dw_i2c_plat_pm_cleanup(dev);
if (!IS_ERR_OR_NULL(dev->rst))
reset_control_assert(dev->rst);
return 0;

View File

@ -791,9 +791,7 @@ static int exynos5_i2c_probe(struct platform_device *pdev)
}
ret = devm_request_irq(&pdev->dev, i2c->irq, exynos5_i2c_irq,
IRQF_NO_SUSPEND | IRQF_ONESHOT,
dev_name(&pdev->dev), i2c);
IRQF_NO_SUSPEND, dev_name(&pdev->dev), i2c);
if (ret != 0) {
dev_err(&pdev->dev, "cannot request HS-I2C IRQ %d\n", i2c->irq);
goto err_clk;

View File

@ -707,8 +707,10 @@ static int fsi_i2c_probe(struct device *dev)
continue;
port = kzalloc(sizeof(*port), GFP_KERNEL);
if (!port)
if (!port) {
of_node_put(np);
break;
}
port->master = i2c;
port->port = port_no;

View File

@ -445,8 +445,7 @@ static int hix5hd2_i2c_probe(struct platform_device *pdev)
hix5hd2_i2c_init(priv);
ret = devm_request_irq(&pdev->dev, irq, hix5hd2_i2c_irq,
IRQF_NO_SUSPEND | IRQF_ONESHOT,
dev_name(&pdev->dev), priv);
IRQF_NO_SUSPEND, dev_name(&pdev->dev), priv);
if (ret != 0) {
dev_err(&pdev->dev, "cannot request HS-I2C IRQ %d\n", irq);
goto err_clk;

View File

@ -292,7 +292,8 @@ struct i801_priv {
#define FEATURE_HOST_NOTIFY BIT(5)
/* Not really a feature, but it's convenient to handle it as such */
#define FEATURE_IDF BIT(15)
#define FEATURE_TCO BIT(16)
#define FEATURE_TCO_SPT BIT(16)
#define FEATURE_TCO_CNL BIT(17)
static const char *i801_feature_names[] = {
"SMBus PEC",
@ -1500,57 +1501,23 @@ static inline unsigned int i801_get_adapter_class(struct i801_priv *priv)
}
#endif
static const struct itco_wdt_platform_data tco_platform_data = {
static const struct itco_wdt_platform_data spt_tco_platform_data = {
.name = "Intel PCH",
.version = 4,
};
static DEFINE_SPINLOCK(p2sb_spinlock);
static void i801_add_tco(struct i801_priv *priv)
static struct platform_device *
i801_add_tco_spt(struct i801_priv *priv, struct pci_dev *pci_dev,
struct resource *tco_res)
{
struct pci_dev *pci_dev = priv->pci_dev;
struct resource tco_res[3], *res;
struct platform_device *pdev;
struct resource *res;
unsigned int devfn;
u32 tco_base, tco_ctl;
u32 base_addr, ctrl_val;
u64 base64_addr;
u32 base_addr;
u8 hidden;
if (!(priv->features & FEATURE_TCO))
return;
pci_read_config_dword(pci_dev, TCOBASE, &tco_base);
pci_read_config_dword(pci_dev, TCOCTL, &tco_ctl);
if (!(tco_ctl & TCOCTL_EN))
return;
memset(tco_res, 0, sizeof(tco_res));
res = &tco_res[ICH_RES_IO_TCO];
res->start = tco_base & ~1;
res->end = res->start + 32 - 1;
res->flags = IORESOURCE_IO;
/*
* Power Management registers.
*/
devfn = PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 2);
pci_bus_read_config_dword(pci_dev->bus, devfn, ACPIBASE, &base_addr);
res = &tco_res[ICH_RES_IO_SMI];
res->start = (base_addr & ~1) + ACPIBASE_SMI_OFF;
res->end = res->start + 3;
res->flags = IORESOURCE_IO;
/*
* Enable the ACPI I/O space.
*/
pci_bus_read_config_dword(pci_dev->bus, devfn, ACPICTRL, &ctrl_val);
ctrl_val |= ACPICTRL_EN;
pci_bus_write_config_dword(pci_dev->bus, devfn, ACPICTRL, ctrl_val);
/*
* We must access the NO_REBOOT bit over the Primary to Sideband
* bridge (P2SB). The BIOS prevents the P2SB device from being
@ -1586,15 +1553,76 @@ static void i801_add_tco(struct i801_priv *priv)
res->end = res->start + 3;
res->flags = IORESOURCE_MEM;
pdev = platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1,
tco_res, 3, &tco_platform_data,
sizeof(tco_platform_data));
if (IS_ERR(pdev)) {
dev_warn(&pci_dev->dev, "failed to create iTCO device\n");
return;
}
return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1,
tco_res, 3, &spt_tco_platform_data,
sizeof(spt_tco_platform_data));
}
priv->tco_pdev = pdev;
static const struct itco_wdt_platform_data cnl_tco_platform_data = {
.name = "Intel PCH",
.version = 6,
};
static struct platform_device *
i801_add_tco_cnl(struct i801_priv *priv, struct pci_dev *pci_dev,
struct resource *tco_res)
{
return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1,
tco_res, 2, &cnl_tco_platform_data,
sizeof(cnl_tco_platform_data));
}
static void i801_add_tco(struct i801_priv *priv)
{
u32 base_addr, tco_base, tco_ctl, ctrl_val;
struct pci_dev *pci_dev = priv->pci_dev;
struct resource tco_res[3], *res;
unsigned int devfn;
/* If we have ACPI based watchdog use that instead */
if (acpi_has_watchdog())
return;
if (!(priv->features & (FEATURE_TCO_SPT | FEATURE_TCO_CNL)))
return;
pci_read_config_dword(pci_dev, TCOBASE, &tco_base);
pci_read_config_dword(pci_dev, TCOCTL, &tco_ctl);
if (!(tco_ctl & TCOCTL_EN))
return;
memset(tco_res, 0, sizeof(tco_res));
res = &tco_res[ICH_RES_IO_TCO];
res->start = tco_base & ~1;
res->end = res->start + 32 - 1;
res->flags = IORESOURCE_IO;
/*
* Power Management registers.
*/
devfn = PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 2);
pci_bus_read_config_dword(pci_dev->bus, devfn, ACPIBASE, &base_addr);
res = &tco_res[ICH_RES_IO_SMI];
res->start = (base_addr & ~1) + ACPIBASE_SMI_OFF;
res->end = res->start + 3;
res->flags = IORESOURCE_IO;
/*
* Enable the ACPI I/O space.
*/
pci_bus_read_config_dword(pci_dev->bus, devfn, ACPICTRL, &ctrl_val);
ctrl_val |= ACPICTRL_EN;
pci_bus_write_config_dword(pci_dev->bus, devfn, ACPICTRL, ctrl_val);
if (priv->features & FEATURE_TCO_CNL)
priv->tco_pdev = i801_add_tco_cnl(priv, pci_dev, tco_res);
else
priv->tco_pdev = i801_add_tco_spt(priv, pci_dev, tco_res);
if (IS_ERR(priv->tco_pdev))
dev_warn(&pci_dev->dev, "failed to create iTCO device\n");
}
#ifdef CONFIG_ACPI
@ -1704,13 +1732,21 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
switch (dev->device) {
case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS:
case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SMBUS:
case PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS:
case PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS:
case PCI_DEVICE_ID_INTEL_LEWISBURG_SMBUS:
case PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS:
case PCI_DEVICE_ID_INTEL_CDF_SMBUS:
case PCI_DEVICE_ID_INTEL_DNV_SMBUS:
case PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS:
priv->features |= FEATURE_I2C_BLOCK_READ;
priv->features |= FEATURE_IRQ;
priv->features |= FEATURE_SMBUS_PEC;
priv->features |= FEATURE_BLOCK_BUFFER;
priv->features |= FEATURE_TCO_SPT;
priv->features |= FEATURE_HOST_NOTIFY;
break;
case PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS:
case PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS:
case PCI_DEVICE_ID_INTEL_CDF_SMBUS:
case PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS:
case PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS:
case PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS:
@ -1720,9 +1756,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
priv->features |= FEATURE_IRQ;
priv->features |= FEATURE_SMBUS_PEC;
priv->features |= FEATURE_BLOCK_BUFFER;
/* If we have ACPI based watchdog use that instead */
if (!acpi_has_watchdog())
priv->features |= FEATURE_TCO;
priv->features |= FEATURE_TCO_CNL;
priv->features |= FEATURE_HOST_NOTIFY;
break;
@ -1921,8 +1955,7 @@ static int i801_suspend(struct device *dev)
static int i801_resume(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
struct i801_priv *priv = pci_get_drvdata(pci_dev);
struct i801_priv *priv = dev_get_drvdata(dev);
i801_enable_host_notify(&priv->adapter);

View File

@ -0,0 +1,230 @@
// SPDX-License-Identifier: GPL-2.0
/*
* I2C driver for stand-alone PCF8584 style adapters on Zorro cards
*
* Original ICY documentation can be found on Aminet:
* https://aminet.net/package/docs/hard/icy
*
* There has been a modern community re-print of this design in 2019:
* https://www.a1k.org/forum/index.php?threads/70106/
*
* The card is basically a Philips PCF8584 connected straight to the
* beginning of the AutoConfig'd address space (register S1 on base+2),
* with /INT on /INT2 on the Zorro bus.
*
* Copyright (c) 2019 Max Staudt <max@enpas.org>
*
* This started as a fork of i2c-elektor.c and has evolved since.
* Thanks go to its authors for providing a base to grow on.
*
*
* IRQ support is currently not implemented.
*
* As it turns out, i2c-algo-pcf is really written with i2c-elektor's
* edge-triggered ISA interrupts in mind, while the Amiga's Zorro bus has
* level-triggered interrupts. This means that once an interrupt occurs, we
* have to tell the PCF8584 to shut up immediately, or it will keep the
* interrupt line busy and cause an IRQ storm.
* However, because of the PCF8584's host-side protocol, there is no good
* way to just quieten it without side effects. Rather, we have to perform
* the next read/write operation straight away, which will reset the /INT
* pin. This entails re-designing the core of i2c-algo-pcf in the future.
* For now, we never request an IRQ from the PCF8584, and poll it instead.
*/
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-pcf.h>
#include <asm/amigaints.h>
#include <linux/zorro.h>
#include "../algos/i2c-algo-pcf.h"
struct icy_i2c {
struct i2c_adapter adapter;
void __iomem *reg_s0;
void __iomem *reg_s1;
struct fwnode_handle *ltc2990_fwnode;
struct i2c_client *ltc2990_client;
};
/*
* Functions called by i2c-algo-pcf
*/
static void icy_pcf_setpcf(void *data, int ctl, int val)
{
struct icy_i2c *i2c = (struct icy_i2c *)data;
u8 __iomem *address = ctl ? i2c->reg_s1 : i2c->reg_s0;
z_writeb(val, address);
}
static int icy_pcf_getpcf(void *data, int ctl)
{
struct icy_i2c *i2c = (struct icy_i2c *)data;
u8 __iomem *address = ctl ? i2c->reg_s1 : i2c->reg_s0;
return z_readb(address);
}
static int icy_pcf_getown(void *data)
{
return 0x55;
}
static int icy_pcf_getclock(void *data)
{
return 0x1c;
}
static void icy_pcf_waitforpin(void *data)
{
usleep_range(50, 150);
}
/*
* Main i2c-icy part
*/
static unsigned short const icy_ltc2990_addresses[] = {
0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END
};
/*
* Additional sensors exposed once this property is applied:
*
* in1 will be the voltage of the 5V rail, divided by 2.
* in2 will be the voltage of the 12V rail, divided by 4.
* temp3 will be measured using a PCB loop next the chip.
*/
static const u32 icy_ltc2990_meas_mode[] = {0, 3};
static const struct property_entry icy_ltc2990_props[] = {
PROPERTY_ENTRY_U32_ARRAY("lltc,meas-mode", icy_ltc2990_meas_mode),
{ }
};
static int icy_probe(struct zorro_dev *z,
const struct zorro_device_id *ent)
{
struct icy_i2c *i2c;
struct i2c_algo_pcf_data *algo_data;
struct fwnode_handle *new_fwnode;
struct i2c_board_info ltc2990_info = {
.type = "ltc2990",
.addr = 0x4c,
};
i2c = devm_kzalloc(&z->dev, sizeof(*i2c), GFP_KERNEL);
if (!i2c)
return -ENOMEM;
algo_data = devm_kzalloc(&z->dev, sizeof(*algo_data), GFP_KERNEL);
if (!algo_data)
return -ENOMEM;
dev_set_drvdata(&z->dev, i2c);
i2c->adapter.dev.parent = &z->dev;
i2c->adapter.owner = THIS_MODULE;
/* i2c->adapter.algo assigned by i2c_pcf_add_bus() */
i2c->adapter.algo_data = algo_data;
strlcpy(i2c->adapter.name, "ICY I2C Zorro adapter",
sizeof(i2c->adapter.name));
if (!devm_request_mem_region(&z->dev,
z->resource.start,
4, i2c->adapter.name))
return -ENXIO;
/* Driver private data */
i2c->reg_s0 = ZTWO_VADDR(z->resource.start);
i2c->reg_s1 = ZTWO_VADDR(z->resource.start + 2);
algo_data->data = i2c;
algo_data->setpcf = icy_pcf_setpcf;
algo_data->getpcf = icy_pcf_getpcf;
algo_data->getown = icy_pcf_getown;
algo_data->getclock = icy_pcf_getclock;
algo_data->waitforpin = icy_pcf_waitforpin;
if (i2c_pcf_add_bus(&i2c->adapter)) {
dev_err(&z->dev, "i2c_pcf_add_bus() failed\n");
return -ENXIO;
}
dev_info(&z->dev, "ICY I2C controller at %pa, IRQ not implemented\n",
&z->resource.start);
/*
* The 2019 a1k.org PCBs have an LTC2990 at 0x4c, so start
* it automatically once ltc2990 is modprobed.
*
* in0 is the voltage of the internal 5V power supply.
* temp1 is the temperature inside the chip.
*
* See property_entry above for in1, in2, temp3.
*/
new_fwnode = fwnode_create_software_node(icy_ltc2990_props, NULL);
if (IS_ERR(new_fwnode)) {
dev_info(&z->dev, "Failed to create fwnode for LTC2990, error: %ld\n",
PTR_ERR(new_fwnode));
} else {
/*
* Store the fwnode so we can destroy it on .remove().
* Only store it on success, as fwnode_remove_software_node()
* is NULL safe, but not PTR_ERR safe.
*/
i2c->ltc2990_fwnode = new_fwnode;
ltc2990_info.fwnode = new_fwnode;
i2c->ltc2990_client =
i2c_new_probed_device(&i2c->adapter,
&ltc2990_info,
icy_ltc2990_addresses,
NULL);
}
return 0;
}
static void icy_remove(struct zorro_dev *z)
{
struct icy_i2c *i2c = dev_get_drvdata(&z->dev);
i2c_unregister_device(i2c->ltc2990_client);
fwnode_remove_software_node(i2c->ltc2990_fwnode);
i2c_del_adapter(&i2c->adapter);
}
static const struct zorro_device_id icy_zorro_tbl[] = {
{ ZORRO_ID(VMC, 15, 0), },
{ 0 }
};
MODULE_DEVICE_TABLE(zorro, icy_zorro_tbl);
static struct zorro_driver icy_driver = {
.name = "i2c-icy",
.id_table = icy_zorro_tbl,
.probe = icy_probe,
.remove = icy_remove,
};
module_driver(icy_driver,
zorro_register_driver,
zorro_unregister_driver);
MODULE_AUTHOR("Max Staudt <max@enpas.org>");
MODULE_DESCRIPTION("I2C bus via PCF8584 on ICY Zorro card");
MODULE_LICENSE("GPL v2");

View File

@ -545,7 +545,6 @@ MODULE_DEVICE_TABLE(of, lpi2c_imx_of_match);
static int lpi2c_imx_probe(struct platform_device *pdev)
{
struct lpi2c_imx_struct *lpi2c_imx;
struct resource *res;
unsigned int temp;
int irq, ret;
@ -553,8 +552,7 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
if (!lpi2c_imx)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
lpi2c_imx->base = devm_ioremap_resource(&pdev->dev, res);
lpi2c_imx->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(lpi2c_imx->base))
return PTR_ERR(lpi2c_imx->base);

View File

@ -20,6 +20,7 @@
*
*/
#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
@ -255,6 +256,12 @@ static const struct of_device_id i2c_imx_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, i2c_imx_dt_ids);
static const struct acpi_device_id i2c_imx_acpi_ids[] = {
{"NXP0001", .driver_data = (kernel_ulong_t)&vf610_i2c_hwdata},
{ }
};
MODULE_DEVICE_TABLE(acpi, i2c_imx_acpi_ids);
static inline int is_imx1_i2c(struct imx_i2c_struct *i2c_imx)
{
return i2c_imx->hwdata->devtype == IMX1_I2C;
@ -1048,14 +1055,13 @@ static const struct i2c_algorithm i2c_imx_algo = {
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);
struct imx_i2c_struct *i2c_imx;
struct resource *res;
struct imxi2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
void __iomem *base;
int irq, ret;
dma_addr_t phy_addr;
const struct imx_i2c_hwdata *match;
dev_dbg(&pdev->dev, "<%s>\n", __func__);
@ -1075,8 +1081,9 @@ static int i2c_imx_probe(struct platform_device *pdev)
if (!i2c_imx)
return -ENOMEM;
if (of_id)
i2c_imx->hwdata = of_id->data;
match = device_get_match_data(&pdev->dev);
if (match)
i2c_imx->hwdata = match;
else
i2c_imx->hwdata = (struct imx_i2c_hwdata *)
platform_get_device_id(pdev)->driver_data;
@ -1089,6 +1096,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
i2c_imx->adapter.nr = pdev->id;
i2c_imx->adapter.dev.of_node = pdev->dev.of_node;
i2c_imx->base = base;
ACPI_COMPANION_SET(&i2c_imx->adapter.dev, ACPI_COMPANION(&pdev->dev));
/* Get I2C clock */
i2c_imx->clk = devm_clk_get(&pdev->dev, NULL);
@ -1247,6 +1255,7 @@ static struct platform_driver i2c_imx_driver = {
.name = DRIVER_NAME,
.pm = &i2c_imx_pm_ops,
.of_match_table = i2c_imx_dt_ids,
.acpi_match_table = i2c_imx_acpi_ids,
},
.id_table = imx_i2c_devtype,
};

View File

@ -781,8 +781,6 @@ static int ismt_dev_init(struct ismt_priv *priv)
if (!priv->hw)
return -ENOMEM;
memset(priv->hw, 0, (ISMT_DESC_ENTRIES * sizeof(struct ismt_desc)));
priv->head = 0;
init_completion(&priv->cmp);

View File

@ -802,7 +802,6 @@ static int mxs_i2c_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct mxs_i2c_dev *i2c;
struct i2c_adapter *adap;
struct resource *res;
int err, irq;
i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
@ -814,8 +813,7 @@ static int mxs_i2c_probe(struct platform_device *pdev)
i2c->dev_type = device_id->driver_data;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
i2c->regs = devm_ioremap_resource(&pdev->dev, res);
i2c->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(i2c->regs))
return PTR_ERR(i2c->regs);

View File

@ -703,7 +703,8 @@ static int ocores_i2c_probe(struct platform_device *pdev)
}
if (ocores_algorithm.master_xfer != ocores_xfer_polling) {
ret = devm_request_irq(&pdev->dev, irq, ocores_isr, 0,
ret = devm_request_any_context_irq(&pdev->dev, irq,
ocores_isr, 0,
pdev->name, i2c);
if (ret) {
dev_err(&pdev->dev, "Cannot claim IRQ\n");

View File

@ -73,6 +73,7 @@
/* Multi-port constants */
#define PIIX4_MAX_ADAPTERS 4
#define HUDSON2_MAIN_PORTS 2 /* HUDSON2, KERNCZ reserves ports 3, 4 */
/* SB800 constants */
#define SB800_PIIX4_SMB_IDX 0xcd6
@ -806,10 +807,12 @@ MODULE_DEVICE_TABLE (pci, piix4_ids);
static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS];
static struct i2c_adapter *piix4_aux_adapter;
static int piix4_adapter_count;
static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
bool sb800_main, u8 port, bool notify_imc,
const char *name, struct i2c_adapter **padap)
u8 hw_port_nr, const char *name,
struct i2c_adapter **padap)
{
struct i2c_adapter *adap;
struct i2c_piix4_adapdata *adapdata;
@ -841,6 +844,12 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
/* set up the sysfs linkage to our parent device */
adap->dev.parent = &dev->dev;
if (has_acpi_companion(&dev->dev)) {
acpi_preset_companion(&adap->dev,
ACPI_COMPANION(&dev->dev),
hw_port_nr);
}
snprintf(adap->name, sizeof(adap->name),
"SMBus PIIX4 adapter%s at %04x", name, smba);
@ -865,8 +874,19 @@ static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba,
int port;
int retval;
for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) {
if (dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS ||
(dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS &&
dev->revision >= 0x1F)) {
piix4_adapter_count = HUDSON2_MAIN_PORTS;
} else {
piix4_adapter_count = PIIX4_MAX_ADAPTERS;
}
for (port = 0; port < piix4_adapter_count; port++) {
u8 hw_port_nr = port == 0 ? 0 : port + 1;
retval = piix4_add_adapter(dev, smba, true, port, notify_imc,
hw_port_nr,
piix4_main_port_names_sb800[port],
&piix4_main_adapters[port]);
if (retval < 0)
@ -937,8 +957,8 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
return retval;
/* Try to register main SMBus adapter, give up if we can't */
retval = piix4_add_adapter(dev, retval, false, 0, false, "",
&piix4_main_adapters[0]);
retval = piix4_add_adapter(dev, retval, false, 0, false, 0,
"", &piix4_main_adapters[0]);
if (retval < 0)
return retval;
}
@ -964,7 +984,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
if (retval > 0) {
/* Try to add the aux adapter if it exists,
* piix4_add_adapter will clean up if this fails */
piix4_add_adapter(dev, retval, false, 0, false,
piix4_add_adapter(dev, retval, false, 0, false, 1,
is_sb800 ? piix4_aux_port_name_sb800 : "",
&piix4_aux_adapter);
}
@ -987,7 +1007,7 @@ static void piix4_adap_remove(struct i2c_adapter *adap)
static void piix4_remove(struct pci_dev *dev)
{
int port = PIIX4_MAX_ADAPTERS;
int port = piix4_adapter_count;
while (--port >= 0) {
if (piix4_main_adapters[port]) {

View File

@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
@ -465,9 +466,9 @@ static int sprd_i2c_clk_init(struct sprd_i2c *i2c_dev)
i2c_dev->clk = devm_clk_get(i2c_dev->dev, "enable");
if (IS_ERR(i2c_dev->clk)) {
dev_warn(i2c_dev->dev, "i2c%d can't get the enable clock\n",
dev_err(i2c_dev->dev, "i2c%d can't get the enable clock\n",
i2c_dev->adap.nr);
i2c_dev->clk = NULL;
return PTR_ERR(i2c_dev->clk);
}
return 0;
@ -477,7 +478,6 @@ static int sprd_i2c_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct sprd_i2c *i2c_dev;
struct resource *res;
u32 prop;
int ret;
@ -487,8 +487,7 @@ static int sprd_i2c_probe(struct platform_device *pdev)
if (!i2c_dev)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
i2c_dev->base = devm_ioremap_resource(dev, res);
i2c_dev->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(i2c_dev->base))
return PTR_ERR(i2c_dev->base);
@ -520,7 +519,10 @@ static int sprd_i2c_probe(struct platform_device *pdev)
if (i2c_dev->bus_freq != 100000 && i2c_dev->bus_freq != 400000)
return -EINVAL;
sprd_i2c_clk_init(i2c_dev);
ret = sprd_i2c_clk_init(i2c_dev);
if (ret)
return ret;
platform_set_drvdata(pdev, i2c_dev);
ret = clk_prepare_enable(i2c_dev->clk);
@ -644,8 +646,7 @@ static struct platform_driver sprd_i2c_driver = {
},
};
static int sprd_i2c_init(void)
{
return platform_driver_register(&sprd_i2c_driver);
}
arch_initcall_sync(sprd_i2c_init);
module_platform_driver(sprd_i2c_driver);
MODULE_DESCRIPTION("Spreadtrum I2C master controller driver");
MODULE_LICENSE("GPL v2");

View File

@ -1809,7 +1809,7 @@ static u32 stm32f7_i2c_func(struct i2c_adapter *adap)
I2C_FUNC_SMBUS_I2C_BLOCK;
}
static struct i2c_algorithm stm32f7_i2c_algo = {
static const struct i2c_algorithm stm32f7_i2c_algo = {
.master_xfer = stm32f7_i2c_xfer,
.smbus_xfer = stm32f7_i2c_smbus_xfer,
.functionality = stm32f7_i2c_func,

View File

@ -526,7 +526,7 @@ static const struct i2c_algorithm synquacer_i2c_algo = {
.functionality = synquacer_i2c_functionality,
};
static struct i2c_adapter synquacer_i2c_ops = {
static const struct i2c_adapter synquacer_i2c_ops = {
.owner = THIS_MODULE,
.name = "synquacer_i2c-adapter",
.algo = &synquacer_i2c_algo,

View File

@ -39,7 +39,7 @@ struct taos_data {
};
/* TAOS TSL2550 EVM */
static struct i2c_board_info tsl2550_info = {
static const struct i2c_board_info tsl2550_info = {
I2C_BOARD_INFO("tsl2550", 0x39),
};

View File

@ -636,7 +636,7 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
dvc_writel(i2c_dev, val, DVC_CTRL_REG1);
}
static int tegra_i2c_runtime_resume(struct device *dev)
static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev)
{
struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
int ret;
@ -665,7 +665,7 @@ static int tegra_i2c_runtime_resume(struct device *dev)
return 0;
}
static int tegra_i2c_runtime_suspend(struct device *dev)
static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
{
struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
@ -713,12 +713,6 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit)
u32 tsu_thd;
u8 tlow, thigh;
err = pm_runtime_get_sync(i2c_dev->dev);
if (err < 0) {
dev_err(i2c_dev->dev, "runtime resume failed %d\n", err);
return err;
}
reset_control_assert(i2c_dev->rst);
udelay(2);
reset_control_deassert(i2c_dev->rst);
@ -772,7 +766,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit)
if (err) {
dev_err(i2c_dev->dev,
"failed changing clock rate: %d\n", err);
goto err;
return err;
}
}
@ -787,23 +781,21 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit)
err = tegra_i2c_flush_fifos(i2c_dev);
if (err)
goto err;
return err;
if (i2c_dev->is_multimaster_mode && i2c_dev->hw->has_slcg_override_reg)
i2c_writel(i2c_dev, I2C_MST_CORE_CLKEN_OVR, I2C_CLKEN_OVERRIDE);
err = tegra_i2c_wait_for_config_load(i2c_dev);
if (err)
goto err;
return err;
if (i2c_dev->irq_disabled) {
i2c_dev->irq_disabled = false;
enable_irq(i2c_dev->irq);
}
err:
pm_runtime_put(i2c_dev->dev);
return err;
return 0;
}
static int tegra_i2c_disable_packet_mode(struct tegra_i2c_dev *i2c_dev)
@ -1616,13 +1608,15 @@ static int tegra_i2c_probe(struct platform_device *pdev)
}
pm_runtime_enable(&pdev->dev);
if (!pm_runtime_enabled(&pdev->dev)) {
if (!pm_runtime_enabled(&pdev->dev))
ret = tegra_i2c_runtime_resume(&pdev->dev);
else
ret = pm_runtime_get_sync(i2c_dev->dev);
if (ret < 0) {
dev_err(&pdev->dev, "runtime resume failed\n");
goto unprepare_div_clk;
}
}
if (i2c_dev->is_multimaster_mode) {
ret = clk_enable(i2c_dev->div_clk);
@ -1666,6 +1660,8 @@ static int tegra_i2c_probe(struct platform_device *pdev)
if (ret)
goto release_dma;
pm_runtime_put(&pdev->dev);
return 0;
release_dma:
@ -1711,8 +1707,7 @@ static int tegra_i2c_remove(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int tegra_i2c_suspend(struct device *dev)
static int __maybe_unused tegra_i2c_suspend(struct device *dev)
{
struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
@ -1721,38 +1716,41 @@ static int tegra_i2c_suspend(struct device *dev)
return 0;
}
static int tegra_i2c_resume(struct device *dev)
static int __maybe_unused tegra_i2c_resume(struct device *dev)
{
struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
int err;
err = tegra_i2c_runtime_resume(dev);
if (err)
return err;
err = tegra_i2c_init(i2c_dev, false);
if (err)
return err;
err = tegra_i2c_runtime_suspend(dev);
if (err)
return err;
i2c_mark_adapter_resumed(&i2c_dev->adapter);
return 0;
}
static const struct dev_pm_ops tegra_i2c_pm = {
SET_SYSTEM_SLEEP_PM_OPS(tegra_i2c_suspend, tegra_i2c_resume)
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(tegra_i2c_suspend, tegra_i2c_resume)
SET_RUNTIME_PM_OPS(tegra_i2c_runtime_suspend, tegra_i2c_runtime_resume,
NULL)
};
#define TEGRA_I2C_PM (&tegra_i2c_pm)
#else
#define TEGRA_I2C_PM NULL
#endif
static struct platform_driver tegra_i2c_driver = {
.probe = tegra_i2c_probe,
.remove = tegra_i2c_remove,
.driver = {
.name = "tegra-i2c",
.of_match_table = tegra_i2c_of_match,
.pm = TEGRA_I2C_PM,
.pm = &tegra_i2c_pm,
},
};

View File

@ -108,7 +108,6 @@ static void uniphier_fi2c_fill_txfifo(struct uniphier_fi2c_priv *priv,
if (fifo_space-- <= 0)
break;
dev_dbg(&priv->adap.dev, "write data: %02x\n", *priv->buf);
writel(*priv->buf++, priv->membase + UNIPHIER_FI2C_DTTX);
priv->len--;
}
@ -124,7 +123,6 @@ static void uniphier_fi2c_drain_rxfifo(struct uniphier_fi2c_priv *priv)
break;
*priv->buf++ = readl(priv->membase + UNIPHIER_FI2C_DTRX);
dev_dbg(&priv->adap.dev, "read data: %02x\n", priv->buf[-1]);
priv->len--;
}
}
@ -142,8 +140,6 @@ static void uniphier_fi2c_clear_irqs(struct uniphier_fi2c_priv *priv,
static void uniphier_fi2c_stop(struct uniphier_fi2c_priv *priv)
{
dev_dbg(&priv->adap.dev, "stop condition\n");
priv->enabled_irqs |= UNIPHIER_FI2C_INT_STOP;
uniphier_fi2c_set_irqs(priv);
writel(UNIPHIER_FI2C_CR_MST | UNIPHIER_FI2C_CR_STO,
@ -160,21 +156,15 @@ static irqreturn_t uniphier_fi2c_interrupt(int irq, void *dev_id)
irq_status = readl(priv->membase + UNIPHIER_FI2C_INT);
irq_status &= priv->enabled_irqs;
dev_dbg(&priv->adap.dev,
"interrupt: enabled_irqs=%04x, irq_status=%04x\n",
priv->enabled_irqs, irq_status);
if (irq_status & UNIPHIER_FI2C_INT_STOP)
goto complete;
if (unlikely(irq_status & UNIPHIER_FI2C_INT_AL)) {
dev_dbg(&priv->adap.dev, "arbitration lost\n");
priv->error = -EAGAIN;
goto complete;
}
if (unlikely(irq_status & UNIPHIER_FI2C_INT_NA)) {
dev_dbg(&priv->adap.dev, "could not get ACK\n");
priv->error = -ENXIO;
if (priv->flags & UNIPHIER_FI2C_RD) {
/*
@ -215,19 +205,15 @@ static irqreturn_t uniphier_fi2c_interrupt(int irq, void *dev_id)
if (unlikely(priv->flags & UNIPHIER_FI2C_MANUAL_NACK)) {
if (priv->len <= UNIPHIER_FI2C_FIFO_SIZE &&
!(priv->flags & UNIPHIER_FI2C_BYTE_WISE)) {
dev_dbg(&priv->adap.dev,
"enable read byte count IRQ\n");
priv->enabled_irqs |= UNIPHIER_FI2C_INT_RB;
uniphier_fi2c_set_irqs(priv);
priv->flags |= UNIPHIER_FI2C_BYTE_WISE;
}
if (priv->len <= 1) {
dev_dbg(&priv->adap.dev, "set NACK\n");
if (priv->len <= 1)
writel(UNIPHIER_FI2C_CR_MST |
UNIPHIER_FI2C_CR_NACK,
priv->membase + UNIPHIER_FI2C_CR);
}
}
goto handled;
}
@ -334,10 +320,6 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap,
bool is_read = msg->flags & I2C_M_RD;
unsigned long time_left, flags;
dev_dbg(&adap->dev, "%s: addr=0x%02x, len=%d, repeat=%d, stop=%d\n",
is_read ? "receive" : "transmit", msg->addr, msg->len,
repeat, stop);
priv->len = msg->len;
priv->buf = msg->buf;
priv->enabled_irqs = UNIPHIER_FI2C_INT_FAULTS;
@ -359,7 +341,6 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap,
else
uniphier_fi2c_tx_init(priv, msg->addr, repeat);
dev_dbg(&adap->dev, "start condition\n");
/*
* For a repeated START condition, writing a slave address to the FIFO
* kicks the controller. So, the UNIPHIER_FI2C_CR register should be
@ -383,7 +364,6 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap,
uniphier_fi2c_recover(priv);
return -ETIMEDOUT;
}
dev_dbg(&adap->dev, "complete\n");
if (unlikely(priv->flags & UNIPHIER_FI2C_DEFER_STOP_COMP)) {
u32 status;
@ -538,7 +518,6 @@ static int uniphier_fi2c_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct uniphier_fi2c_priv *priv;
struct resource *regs;
u32 bus_speed;
unsigned long clk_rate;
int irq, ret;
@ -547,8 +526,7 @@ static int uniphier_fi2c_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->membase = devm_ioremap_resource(dev, regs);
priv->membase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->membase))
return PTR_ERR(priv->membase);

View File

@ -71,7 +71,6 @@ static int uniphier_i2c_xfer_byte(struct i2c_adapter *adap, u32 txdata,
reinit_completion(&priv->comp);
txdata |= UNIPHIER_I2C_DTRM_IRQEN;
dev_dbg(&adap->dev, "write data: 0x%04x\n", txdata);
writel(txdata, priv->membase + UNIPHIER_I2C_DTRM);
time_left = wait_for_completion_timeout(&priv->comp, adap->timeout);
@ -81,8 +80,6 @@ static int uniphier_i2c_xfer_byte(struct i2c_adapter *adap, u32 txdata,
}
rxdata = readl(priv->membase + UNIPHIER_I2C_DREC);
dev_dbg(&adap->dev, "read data: 0x%04x\n", rxdata);
if (rxdatap)
*rxdatap = rxdata;
@ -98,14 +95,11 @@ static int uniphier_i2c_send_byte(struct i2c_adapter *adap, u32 txdata)
if (ret)
return ret;
if (unlikely(rxdata & UNIPHIER_I2C_DREC_LAB)) {
dev_dbg(&adap->dev, "arbitration lost\n");
if (unlikely(rxdata & UNIPHIER_I2C_DREC_LAB))
return -EAGAIN;
}
if (unlikely(rxdata & UNIPHIER_I2C_DREC_LRB)) {
dev_dbg(&adap->dev, "could not get ACK\n");
if (unlikely(rxdata & UNIPHIER_I2C_DREC_LRB))
return -ENXIO;
}
return 0;
}
@ -115,7 +109,6 @@ static int uniphier_i2c_tx(struct i2c_adapter *adap, u16 addr, u16 len,
{
int ret;
dev_dbg(&adap->dev, "start condition\n");
ret = uniphier_i2c_send_byte(adap, addr << 1 |
UNIPHIER_I2C_DTRM_STA |
UNIPHIER_I2C_DTRM_NACK);
@ -137,7 +130,6 @@ static int uniphier_i2c_rx(struct i2c_adapter *adap, u16 addr, u16 len,
{
int ret;
dev_dbg(&adap->dev, "start condition\n");
ret = uniphier_i2c_send_byte(adap, addr << 1 |
UNIPHIER_I2C_DTRM_STA |
UNIPHIER_I2C_DTRM_NACK |
@ -161,7 +153,6 @@ static int uniphier_i2c_rx(struct i2c_adapter *adap, u16 addr, u16 len,
static int uniphier_i2c_stop(struct i2c_adapter *adap)
{
dev_dbg(&adap->dev, "stop condition\n");
return uniphier_i2c_send_byte(adap, UNIPHIER_I2C_DTRM_STO |
UNIPHIER_I2C_DTRM_NACK);
}
@ -173,9 +164,6 @@ static int uniphier_i2c_master_xfer_one(struct i2c_adapter *adap,
bool recovery = false;
int ret;
dev_dbg(&adap->dev, "%s: addr=0x%02x, len=%d, stop=%d\n",
is_read ? "receive" : "transmit", msg->addr, msg->len, stop);
if (is_read)
ret = uniphier_i2c_rx(adap, msg->addr, msg->len, msg->buf);
else
@ -326,7 +314,6 @@ static int uniphier_i2c_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct uniphier_i2c_priv *priv;
struct resource *regs;
u32 bus_speed;
unsigned long clk_rate;
int irq, ret;
@ -335,8 +322,7 @@ static int uniphier_i2c_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->membase = devm_ioremap_resource(dev, regs);
priv->membase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->membase))
return PTR_ERR(priv->membase);

View File

@ -350,13 +350,11 @@ static int i2c_device_probe(struct device *dev)
return -ENODEV;
if (client->flags & I2C_CLIENT_WAKE) {
int wakeirq = -ENOENT;
int wakeirq;
if (dev->of_node) {
wakeirq = of_irq_get_byname(dev->of_node, "wakeup");
if (wakeirq == -EPROBE_DEFER)
return wakeirq;
}
device_init_wakeup(&client->dev, true);
@ -966,7 +964,7 @@ struct i2c_client *devm_i2c_new_dummy_device(struct device *dev,
EXPORT_SYMBOL_GPL(devm_i2c_new_dummy_device);
/**
* i2c_new_secondary_device - Helper to get the instantiated secondary address
* i2c_new_ancillary_device - Helper to get the instantiated secondary address
* and create the associated device
* @client: Handle to the primary client
* @name: Handle to specify which secondary address to get
@ -985,9 +983,9 @@ EXPORT_SYMBOL_GPL(devm_i2c_new_dummy_device);
* cell whose "reg-names" value matches the slave name.
*
* This returns the new i2c client, which should be saved for later use with
* i2c_unregister_device(); or NULL to indicate an error.
* i2c_unregister_device(); or an ERR_PTR to describe the error.
*/
struct i2c_client *i2c_new_secondary_device(struct i2c_client *client,
struct i2c_client *i2c_new_ancillary_device(struct i2c_client *client,
const char *name,
u16 default_addr)
{
@ -1002,9 +1000,9 @@ struct i2c_client *i2c_new_secondary_device(struct i2c_client *client,
}
dev_dbg(&client->adapter->dev, "Address for %s : 0x%x\n", name, addr);
return i2c_new_dummy(client->adapter, addr);
return i2c_new_dummy_device(client->adapter, addr);
}
EXPORT_SYMBOL_GPL(i2c_new_secondary_device);
EXPORT_SYMBOL_GPL(i2c_new_ancillary_device);
/* ------------------------------------------------------------------------- */

View File

@ -11,6 +11,13 @@
* pointer, yet implementation is deferred until the need actually arises.
*/
/*
* FIXME: What to do if only 8 bits of a 16 bit address are sent?
* The ST-M24C64 sends only 0xff then. Needs verification with other
* EEPROMs, though. We currently use the 8 bit as a valid address.
*/
#include <linux/bitfield.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/module.h>
@ -21,12 +28,18 @@
struct eeprom_data {
struct bin_attribute bin;
bool first_write;
spinlock_t buffer_lock;
u8 buffer_idx;
u16 buffer_idx;
u16 address_mask;
u8 num_address_bytes;
u8 idx_write_cnt;
u8 buffer[];
};
#define I2C_SLAVE_BYTELEN GENMASK(15, 0)
#define I2C_SLAVE_FLAG_ADDR16 BIT(16)
#define I2C_SLAVE_DEVICE_MAGIC(_len, _flags) ((_flags) | (_len))
static int i2c_slave_eeprom_slave_cb(struct i2c_client *client,
enum i2c_slave_event event, u8 *val)
{
@ -34,12 +47,14 @@ static int i2c_slave_eeprom_slave_cb(struct i2c_client *client,
switch (event) {
case I2C_SLAVE_WRITE_RECEIVED:
if (eeprom->first_write) {
eeprom->buffer_idx = *val;
eeprom->first_write = false;
if (eeprom->idx_write_cnt < eeprom->num_address_bytes) {
if (eeprom->idx_write_cnt == 0)
eeprom->buffer_idx = 0;
eeprom->buffer_idx = *val | (eeprom->buffer_idx << 8);
eeprom->idx_write_cnt++;
} else {
spin_lock(&eeprom->buffer_lock);
eeprom->buffer[eeprom->buffer_idx++] = *val;
eeprom->buffer[eeprom->buffer_idx++ & eeprom->address_mask] = *val;
spin_unlock(&eeprom->buffer_lock);
}
break;
@ -50,7 +65,7 @@ static int i2c_slave_eeprom_slave_cb(struct i2c_client *client,
/* fallthrough */
case I2C_SLAVE_READ_REQUESTED:
spin_lock(&eeprom->buffer_lock);
*val = eeprom->buffer[eeprom->buffer_idx];
*val = eeprom->buffer[eeprom->buffer_idx & eeprom->address_mask];
spin_unlock(&eeprom->buffer_lock);
/*
* Do not increment buffer_idx here, because we don't know if
@ -61,7 +76,7 @@ static int i2c_slave_eeprom_slave_cb(struct i2c_client *client,
case I2C_SLAVE_STOP:
case I2C_SLAVE_WRITE_REQUESTED:
eeprom->first_write = true;
eeprom->idx_write_cnt = 0;
break;
default:
@ -105,13 +120,16 @@ static int i2c_slave_eeprom_probe(struct i2c_client *client, const struct i2c_de
{
struct eeprom_data *eeprom;
int ret;
unsigned size = id->driver_data;
unsigned int size = FIELD_GET(I2C_SLAVE_BYTELEN, id->driver_data);
unsigned int flag_addr16 = FIELD_GET(I2C_SLAVE_FLAG_ADDR16, id->driver_data);
eeprom = devm_kzalloc(&client->dev, sizeof(struct eeprom_data) + size, GFP_KERNEL);
if (!eeprom)
return -ENOMEM;
eeprom->first_write = true;
eeprom->idx_write_cnt = 0;
eeprom->num_address_bytes = flag_addr16 ? 2 : 1;
eeprom->address_mask = size - 1;
spin_lock_init(&eeprom->buffer_lock);
i2c_set_clientdata(client, eeprom);
@ -146,7 +164,9 @@ static int i2c_slave_eeprom_remove(struct i2c_client *client)
}
static const struct i2c_device_id i2c_slave_eeprom_id[] = {
{ "slave-24c02", 2048 / 8 },
{ "slave-24c02", I2C_SLAVE_DEVICE_MAGIC(2048 / 8, 0) },
{ "slave-24c32", I2C_SLAVE_DEVICE_MAGIC(32768 / 8, I2C_SLAVE_FLAG_ADDR16) },
{ "slave-24c64", I2C_SLAVE_DEVICE_MAGIC(65536 / 8, I2C_SLAVE_FLAG_ADDR16) },
{ }
};
MODULE_DEVICE_TABLE(i2c, i2c_slave_eeprom_id);

View File

@ -183,14 +183,14 @@ static int adv748x_initialise_clients(struct adv748x_state *state)
int ret;
for (i = ADV748X_PAGE_DPLL; i < ADV748X_PAGE_MAX; ++i) {
state->i2c_clients[i] = i2c_new_secondary_device(
state->i2c_clients[i] = i2c_new_ancillary_device(
state->client,
adv748x_default_addresses[i].name,
adv748x_default_addresses[i].default_addr);
if (state->i2c_clients[i] == NULL) {
if (IS_ERR(state->i2c_clients[i])) {
adv_err(state, "failed to create i2c client %u\n", i);
return -ENOMEM;
return PTR_ERR(state->i2c_clients[i]);
}
ret = adv748x_configure_regmap(state, i);

View File

@ -2862,10 +2862,8 @@ static void adv76xx_unregister_clients(struct adv76xx_state *state)
{
unsigned int i;
for (i = 1; i < ARRAY_SIZE(state->i2c_clients); ++i) {
if (state->i2c_clients[i])
for (i = 1; i < ARRAY_SIZE(state->i2c_clients); ++i)
i2c_unregister_device(state->i2c_clients[i]);
}
}
static struct i2c_client *adv76xx_dummy_client(struct v4l2_subdev *sd,
@ -2878,14 +2876,14 @@ static struct i2c_client *adv76xx_dummy_client(struct v4l2_subdev *sd,
struct i2c_client *new_client;
if (pdata && pdata->i2c_addresses[page])
new_client = i2c_new_dummy(client->adapter,
new_client = i2c_new_dummy_device(client->adapter,
pdata->i2c_addresses[page]);
else
new_client = i2c_new_secondary_device(client,
new_client = i2c_new_ancillary_device(client,
adv76xx_default_addresses[page].name,
adv76xx_default_addresses[page].default_addr);
if (new_client)
if (!IS_ERR(new_client))
io_write(sd, io_reg, new_client->addr << 1);
return new_client;
@ -3516,15 +3514,19 @@ static int adv76xx_probe(struct i2c_client *client,
}
for (i = 1; i < ADV76XX_PAGE_MAX; ++i) {
struct i2c_client *dummy_client;
if (!(BIT(i) & state->info->page_mask))
continue;
state->i2c_clients[i] = adv76xx_dummy_client(sd, i);
if (!state->i2c_clients[i]) {
err = -EINVAL;
dummy_client = adv76xx_dummy_client(sd, i);
if (IS_ERR(dummy_client)) {
err = PTR_ERR(dummy_client);
v4l2_err(sd, "failed to create i2c client %u\n", i);
goto err_i2c;
}
state->i2c_clients[i] = dummy_client;
}
INIT_DELAYED_WORK(&state->delayed_work_enable_hotplug,

View File

@ -14,7 +14,6 @@
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/mod_devicetable.h>
#include <linux/log2.h>
#include <linux/bitops.h>
#include <linux/jiffies.h>
#include <linux/property.h>

View File

@ -48,6 +48,7 @@
/* Includes */
#include <linux/acpi.h> /* For ACPI support */
#include <linux/bits.h> /* For BIT() */
#include <linux/module.h> /* For module specific items */
#include <linux/moduleparam.h> /* For new moduleparam's */
#include <linux/types.h> /* For standard types (like size_t) */
@ -215,6 +216,23 @@ static int update_no_reboot_bit_mem(void *priv, bool set)
return 0;
}
static int update_no_reboot_bit_cnt(void *priv, bool set)
{
struct iTCO_wdt_private *p = priv;
u16 val, newval;
val = inw(TCO1_CNT(p));
if (set)
val |= BIT(0);
else
val &= ~BIT(0);
outw(val, TCO1_CNT(p));
newval = inw(TCO1_CNT(p));
/* make sure the update is successful */
return val != newval ? -EIO : 0;
}
static void iTCO_wdt_no_reboot_bit_setup(struct iTCO_wdt_private *p,
struct itco_wdt_platform_data *pdata)
{
@ -224,7 +242,9 @@ static void iTCO_wdt_no_reboot_bit_setup(struct iTCO_wdt_private *p,
return;
}
if (p->iTCO_version >= 2)
if (p->iTCO_version >= 6)
p->update_no_reboot_bit = update_no_reboot_bit_cnt;
else if (p->iTCO_version >= 2)
p->update_no_reboot_bit = update_no_reboot_bit_mem;
else if (p->iTCO_version == 1)
p->update_no_reboot_bit = update_no_reboot_bit_pci;
@ -452,7 +472,8 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
* Get the Memory-Mapped GCS or PMC register, we need it for the
* NO_REBOOT flag (TCO v2 and v3).
*/
if (p->iTCO_version >= 2 && !pdata->update_no_reboot_bit) {
if (p->iTCO_version >= 2 && p->iTCO_version < 6 &&
!pdata->update_no_reboot_bit) {
p->gcs_pmc_res = platform_get_resource(pdev,
IORESOURCE_MEM,
ICH_RES_MEM_GCS_PMC);
@ -502,6 +523,7 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
/* Clear out the (probably old) status */
switch (p->iTCO_version) {
case 6:
case 5:
case 4:
outw(0x0008, TCO1_STS(p)); /* Clear the Time Out Status bit */

View File

@ -473,7 +473,7 @@ extern struct i2c_client *
devm_i2c_new_dummy_device(struct device *dev, struct i2c_adapter *adap, u16 address);
extern struct i2c_client *
i2c_new_secondary_device(struct i2c_client *client,
i2c_new_ancillary_device(struct i2c_client *client,
const char *name,
u16 default_addr);