Commit 351c8a09 authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents 3cf7487c 8ebf15e9
Broadcom BCM2835 I2C controller Broadcom BCM2835 I2C controller
Required properties: 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. - reg: Should contain register location and length.
- interrupts: Should contain interrupt. - interrupts: Should contain interrupt.
- clocks : The clock feeding the I2C controller. - clocks : The clock feeding the I2C controller.
......
...@@ -7865,6 +7865,12 @@ S: Maintained ...@@ -7865,6 +7865,12 @@ S: Maintained
F: drivers/mfd/lpc_ich.c F: drivers/mfd/lpc_ich.c
F: drivers/gpio/gpio-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 IDE SUBSYSTEM
M: "David S. Miller" <davem@davemloft.net> M: "David S. Miller" <davem@davemloft.net>
L: linux-ide@vger.kernel.org L: linux-ide@vger.kernel.org
...@@ -13791,7 +13797,7 @@ F: drivers/clk/renesas/ ...@@ -13791,7 +13797,7 @@ F: drivers/clk/renesas/
RENESAS EMEV2 I2C DRIVER RENESAS EMEV2 I2C DRIVER
M: Wolfram Sang <wsa+renesas@sang-engineering.com> M: Wolfram Sang <wsa+renesas@sang-engineering.com>
S: Supported 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 F: drivers/i2c/busses/i2c-emev2.c
RENESAS ETHERNET DRIVERS RENESAS ETHERNET DRIVERS
...@@ -13813,15 +13819,15 @@ F: drivers/iio/adc/rcar-gyroadc.c ...@@ -13813,15 +13819,15 @@ F: drivers/iio/adc/rcar-gyroadc.c
RENESAS R-CAR I2C DRIVERS RENESAS R-CAR I2C DRIVERS
M: Wolfram Sang <wsa+renesas@sang-engineering.com> M: Wolfram Sang <wsa+renesas@sang-engineering.com>
S: Supported S: Supported
F: Documentation/devicetree/bindings/i2c/i2c-rcar.txt F: Documentation/devicetree/bindings/i2c/renesas,i2c.txt
F: Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt F: Documentation/devicetree/bindings/i2c/renesas,iic.txt
F: drivers/i2c/busses/i2c-rcar.c F: drivers/i2c/busses/i2c-rcar.c
F: drivers/i2c/busses/i2c-sh_mobile.c F: drivers/i2c/busses/i2c-sh_mobile.c
RENESAS RIIC DRIVER RENESAS RIIC DRIVER
M: Chris Brandt <chris.brandt@renesas.com> M: Chris Brandt <chris.brandt@renesas.com>
S: Supported 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 F: drivers/i2c/busses/i2c-riic.c
RENESAS USB PHY DRIVER RENESAS USB PHY DRIVER
......
...@@ -160,11 +160,17 @@ static const struct apd_device_desc hip08_i2c_desc = { ...@@ -160,11 +160,17 @@ static const struct apd_device_desc hip08_i2c_desc = {
.setup = acpi_apd_setup, .setup = acpi_apd_setup,
.fixed_clk_rate = 250000000, .fixed_clk_rate = 250000000,
}; };
static const struct apd_device_desc thunderx2_i2c_desc = { static const struct apd_device_desc thunderx2_i2c_desc = {
.setup = acpi_apd_setup, .setup = acpi_apd_setup,
.fixed_clk_rate = 125000000, .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 = { static const struct apd_device_desc hip08_spi_desc = {
.setup = acpi_apd_setup, .setup = acpi_apd_setup,
.fixed_clk_rate = 250000000, .fixed_clk_rate = 250000000,
...@@ -238,6 +244,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = { ...@@ -238,6 +244,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = {
{ "HISI02A1", APD_ADDR(hip07_i2c_desc) }, { "HISI02A1", APD_ADDR(hip07_i2c_desc) },
{ "HISI02A2", APD_ADDR(hip08_i2c_desc) }, { "HISI02A2", APD_ADDR(hip08_i2c_desc) },
{ "HISI0173", APD_ADDR(hip08_spi_desc) }, { "HISI0173", APD_ADDR(hip08_spi_desc) },
{ "NXP0001", APD_ADDR(nxp_i2c_desc) },
#endif #endif
{ } { }
}; };
......
...@@ -978,10 +978,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv) ...@@ -978,10 +978,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv)
{ {
int ret; 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); ADV7511_CEC_I2C_ADDR_DEFAULT);
if (!adv->i2c_cec) if (IS_ERR(adv->i2c_cec))
return -EINVAL; return PTR_ERR(adv->i2c_cec);
i2c_set_clientdata(adv->i2c_cec, adv); i2c_set_clientdata(adv->i2c_cec, adv);
adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec, 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) ...@@ -1162,20 +1162,20 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
adv7511_packet_disable(adv7511, 0xffff); 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); ADV7511_EDID_I2C_ADDR_DEFAULT);
if (!adv7511->i2c_edid) { if (IS_ERR(adv7511->i2c_edid)) {
ret = -EINVAL; ret = PTR_ERR(adv7511->i2c_edid);
goto uninit_regulators; goto uninit_regulators;
} }
regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR,
adv7511->i2c_edid->addr << 1); 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); ADV7511_PACKET_I2C_ADDR_DEFAULT);
if (!adv7511->i2c_packet) { if (IS_ERR(adv7511->i2c_packet)) {
ret = -EINVAL; ret = PTR_ERR(adv7511->i2c_packet);
goto err_i2c_unregister_edid; goto err_i2c_unregister_edid;
} }
......
...@@ -429,6 +429,7 @@ config I2C_AXXIA ...@@ -429,6 +429,7 @@ config I2C_AXXIA
tristate "Axxia I2C controller" tristate "Axxia I2C controller"
depends on ARCH_AXXIA || COMPILE_TEST depends on ARCH_AXXIA || COMPILE_TEST
default ARCH_AXXIA default ARCH_AXXIA
select I2C_SLAVE
help help
Say yes if you want to support the I2C bus on Axxia platforms. Say yes if you want to support the I2C bus on Axxia platforms.
...@@ -977,7 +978,7 @@ config I2C_SIRF ...@@ -977,7 +978,7 @@ config I2C_SIRF
will be called i2c-sirf. will be called i2c-sirf.
config I2C_SPRD config I2C_SPRD
bool "Spreadtrum I2C interface" tristate "Spreadtrum I2C interface"
depends on I2C=y && ARCH_SPRD depends on I2C=y && ARCH_SPRD
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
...@@ -1309,6 +1310,20 @@ config I2C_ELEKTOR ...@@ -1309,6 +1310,20 @@ config I2C_ELEKTOR
This support is also available as a module. If so, the module This support is also available as a module. If so, the module
will be called i2c-elektor. 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 config I2C_MLXCPLD
tristate "Mellanox I2C driver" tristate "Mellanox I2C driver"
depends on X86_64 depends on X86_64
......
...@@ -140,6 +140,7 @@ obj-$(CONFIG_I2C_BCM_KONA) += i2c-bcm-kona.o ...@@ -140,6 +140,7 @@ obj-$(CONFIG_I2C_BCM_KONA) += i2c-bcm-kona.o
obj-$(CONFIG_I2C_BRCMSTB) += i2c-brcmstb.o obj-$(CONFIG_I2C_BRCMSTB) += i2c-brcmstb.o
obj-$(CONFIG_I2C_CROS_EC_TUNNEL) += i2c-cros-ec-tunnel.o obj-$(CONFIG_I2C_CROS_EC_TUNNEL) += i2c-cros-ec-tunnel.o
obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.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_MLXCPLD) += i2c-mlxcpld.o
obj-$(CONFIG_I2C_OPAL) += i2c-opal.o obj-$(CONFIG_I2C_OPAL) += i2c-opal.o
obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o
......
...@@ -77,6 +77,40 @@ ...@@ -77,6 +77,40 @@
MST_STATUS_IP) MST_STATUS_IP)
#define MST_TX_BYTES_XFRD 0x50 #define MST_TX_BYTES_XFRD 0x50
#define MST_RX_BYTES_XFRD 0x54 #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_HIGH_PERIOD 0x80
#define SCL_LOW_PERIOD 0x84 #define SCL_LOW_PERIOD 0x84
#define SPIKE_FLTR_LEN 0x88 #define SPIKE_FLTR_LEN 0x88
...@@ -111,6 +145,8 @@ struct axxia_i2c_dev { ...@@ -111,6 +145,8 @@ struct axxia_i2c_dev {
struct clk *i2c_clk; struct clk *i2c_clk;
u32 bus_clk_rate; u32 bus_clk_rate;
bool last; bool last;
struct i2c_client *slave;
int irq;
}; };
static void i2c_int_disable(struct axxia_i2c_dev *idev, u32 mask) 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) ...@@ -276,13 +312,65 @@ static int axxia_i2c_fill_tx_fifo(struct axxia_i2c_dev *idev)
return ret; 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) static irqreturn_t axxia_i2c_isr(int irq, void *_dev)
{ {
struct axxia_i2c_dev *idev = _dev; struct axxia_i2c_dev *idev = _dev;
irqreturn_t ret = IRQ_NONE;
u32 status; u32 status;
if (!(readl(idev->base + INTERRUPT_STATUS) & INT_MST)) status = readl(idev->base + INTERRUPT_STATUS);
return IRQ_NONE;
if (status & INT_SLV)
ret = axxia_i2c_slv_isr(idev);
if (!(status & INT_MST))
return ret;
/* Read interrupt status bits */ /* Read interrupt status bits */
status = readl(idev->base + MST_INT_STATUS); status = readl(idev->base + MST_INT_STATUS);
...@@ -583,9 +671,58 @@ static u32 axxia_i2c_func(struct i2c_adapter *adap) ...@@ -583,9 +671,58 @@ static u32 axxia_i2c_func(struct i2c_adapter *adap)
return caps; 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 = { static const struct i2c_algorithm axxia_i2c_algo = {
.master_xfer = axxia_i2c_xfer, .master_xfer = axxia_i2c_xfer,
.functionality = axxia_i2c_func, .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 = { static const struct i2c_adapter_quirks axxia_i2c_quirks = {
...@@ -599,7 +736,6 @@ static int axxia_i2c_probe(struct platform_device *pdev) ...@@ -599,7 +736,6 @@ static int axxia_i2c_probe(struct platform_device *pdev)
struct axxia_i2c_dev *idev = NULL; struct axxia_i2c_dev *idev = NULL;
struct resource *res; struct resource *res;
void __iomem *base; void __iomem *base;
int irq;
int ret = 0; int ret = 0;
idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL); idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL);
...@@ -611,10 +747,10 @@ static int axxia_i2c_probe(struct platform_device *pdev) ...@@ -611,10 +747,10 @@ static int axxia_i2c_probe(struct platform_device *pdev)
if (IS_ERR(base)) if (IS_ERR(base))
return PTR_ERR(base); return PTR_ERR(base);
irq = platform_get_irq(pdev, 0); idev->irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (idev->irq < 0) {
dev_err(&pdev->dev, "missing interrupt resource\n"); dev_err(&pdev->dev, "missing interrupt resource\n");
return irq; return idev->irq;
} }
idev->i2c_clk = devm_clk_get(&pdev->dev, "i2c"); idev->i2c_clk = devm_clk_get(&pdev->dev, "i2c");
...@@ -643,10 +779,10 @@ static int axxia_i2c_probe(struct platform_device *pdev) ...@@ -643,10 +779,10 @@ static int axxia_i2c_probe(struct platform_device *pdev)
goto error_disable_clk; 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); pdev->name, idev);
if (ret) { 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; goto error_disable_clk;
} }
......
...@@ -808,7 +808,7 @@ static struct i2c_algorithm bcm_iproc_algo = { ...@@ -808,7 +808,7 @@ static struct i2c_algorithm bcm_iproc_algo = {
.unreg_slave = bcm_iproc_i2c_unreg_slave, .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, .max_read_len = M_RX_MAX_READ_LEN,
}; };
...@@ -922,7 +922,9 @@ static int bcm_iproc_i2c_probe(struct platform_device *pdev) ...@@ -922,7 +922,9 @@ static int bcm_iproc_i2c_probe(struct platform_device *pdev)
adap = &iproc_i2c->adapter; adap = &iproc_i2c->adapter;
i2c_set_adapdata(adap, iproc_i2c); 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->algo = &bcm_iproc_algo;
adap->quirks = &bcm_iproc_i2c_quirks; adap->quirks = &bcm_iproc_i2c_quirks;
adap->dev.parent = &pdev->dev; adap->dev.parent = &pdev->dev;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -389,7 +390,7 @@ static const struct i2c_algorithm bcm2835_i2c_algo = { ...@@ -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 * http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html
* https://www.raspberrypi.org/forums/viewtopic.php?p=146272 * https://www.raspberrypi.org/forums/viewtopic.php?p=146272
*/ */
...@@ -471,11 +472,12 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) ...@@ -471,11 +472,12 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
i2c_set_adapdata(adap, i2c_dev); i2c_set_adapdata(adap, i2c_dev);
adap->owner = THIS_MODULE; adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_DEPRECATED; 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->algo = &bcm2835_i2c_algo;
adap->dev.parent = &pdev->dev; adap->dev.parent = &pdev->dev;
adap->dev.of_node = pdev->dev.of_node; 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); bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 0);
...@@ -501,7 +503,8 @@ static int bcm2835_i2c_remove(struct platform_device *pdev) ...@@ -501,7 +503,8 @@ static int bcm2835_i2c_remove(struct platform_device *pdev)
} }
static const struct of_device_id bcm2835_i2c_of_match[] = { 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); MODULE_DEVICE_TABLE(of, bcm2835_i2c_of_match);
......
...@@ -178,6 +178,51 @@ static const struct i2c_algorithm cht_wc_i2c_adap_algo = { ...@@ -178,6 +178,51 @@ static const struct i2c_algorithm cht_wc_i2c_adap_algo = {
.smbus_xfer = cht_wc_i2c_adap_smbus_xfer, .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 ****/ /**** irqchip for the client connected to the extchgr i2c adapter ****/
static void cht_wc_i2c_irq_lock(struct irq_data *data) 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) ...@@ -286,6 +331,7 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
adap->adapter.owner = THIS_MODULE; adap->adapter.owner = THIS_MODULE;
adap->adapter.class = I2C_CLASS_HWMON; adap->adapter.class = I2C_CLASS_HWMON;
adap->adapter.algo = &cht_wc_i2c_adap_algo; 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", strlcpy(adap->adapter.name, "PMIC I2C Adapter",
sizeof(adap->adapter.name)); sizeof(adap->adapter.name));
adap->adapter.dev.parent = &pdev->dev; adap->adapter.dev.parent = &pdev->dev;
...@@ -363,8 +409,7 @@ static int cht_wc_i2c_adap_i2c_remove(struct platform_device *pdev) ...@@ -363,8 +409,7 @@ static int cht_wc_i2c_adap_i2c_remove(struct platform_device *pdev)
{ {
struct cht_wc_i2c_adap *adap = platform_get_drvdata(pdev); struct cht_wc_i2c_adap *adap = platform_get_drvdata(pdev);
if (adap->client) i2c_unregister_device(adap->client);
i2c_unregister_device(adap->client);
i2c_del_adapter(&adap->adapter); i2c_del_adapter(&adap->adapter);
irq_domain_remove(adap->irq_domain); irq_domain_remove(adap->irq_domain);
......
...@@ -655,15 +655,11 @@ static int i2c_dw_init_recovery_info(struct dw_i2c_dev *dev) ...@@ -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_bus_recovery_info *rinfo = &dev->rinfo;
struct i2c_adapter *adap = &dev->adapter; struct i2c_adapter *adap = &dev->adapter;
struct gpio_desc *gpio; struct gpio_desc *gpio;
int r;
gpio = devm_gpiod_get_optional(dev->dev, "scl", GPIOD_OUT_HIGH);
gpio = devm_gpiod_get(dev->dev, "scl", GPIOD_OUT_HIGH); if (IS_ERR_OR_NULL(gpio))
if (IS_ERR(gpio)) { return PTR_ERR_OR_ZERO(gpio);
r = PTR_ERR(gpio);
if (r == -ENOENT || r == -ENOSYS)
return 0;
return r;
}
rinfo->scl_gpiod = gpio; rinfo->scl_gpiod = gpio;
gpio = devm_gpiod_get_optional(dev->dev, "sda", GPIOD_IN); gpio = devm_gpiod_get_optional(dev->dev, "sda", GPIOD_IN);
......
...@@ -33,6 +33,7 @@ enum dw_pci_ctl_id_t { ...@@ -33,6 +33,7 @@ enum dw_pci_ctl_id_t {
baytrail, baytrail,
cherrytrail, cherrytrail,
haswell, haswell,
elkhartlake,
}; };
struct dw_scl_sda_cfg { struct dw_scl_sda_cfg {
...@@ -168,13 +169,20 @@ static struct dw_pci_controller dw_pci_controllers[] = { ...@@ -168,13 +169,20 @@ static struct dw_pci_controller dw_pci_controllers[] = {
.flags = MODEL_CHERRYTRAIL, .flags = MODEL_CHERRYTRAIL,
.scl_sda_cfg = &byt_config, .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 #ifdef CONFIG_PM
static int i2c_dw_pci_suspend(struct device *dev) static int i2c_dw_pci_suspend(struct device *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev); struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
struct dw_i2c_dev *i_dev = pci_get_drvdata(pdev);
i_dev->suspended = true; i_dev->suspended = true;
i_dev->disable(i_dev); i_dev->disable(i_dev);
...@@ -184,8 +192,7 @@ static int i2c_dw_pci_suspend(struct device *dev) ...@@ -184,8 +192,7 @@ static int i2c_dw_pci_suspend(struct device *dev)
static int i2c_dw_pci_resume(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 = dev_get_drvdata(dev);
struct dw_i2c_dev *i_dev = pci_get_drvdata(pdev);
int ret; int ret;
ret = i_dev->init(i_dev); ret = i_dev->init(i_dev);
...@@ -227,6 +234,8 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, ...@@ -227,6 +234,8 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
return r; return r;
} }
pci_set_master(pdev);
r = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev)); r = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
if (r) { if (r) {
dev_err(&pdev->dev, "I/O memory remapping failed\n"); dev_err(&pdev->dev, "I/O memory remapping failed\n");
...@@ -237,18 +246,24 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, ...@@ -237,18 +246,24 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
r = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
if (r < 0)
return r;
dev->clk = NULL; dev->clk = NULL;
dev->controller = controller; dev->controller = controller;
dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
dev->base = pcim_iomap_table(pdev)[0]; dev->base = pcim_iomap_table(pdev)[0];
dev->dev = &pdev->dev; dev->dev = &pdev->dev;
dev->irq = pdev->irq; dev->irq = pci_irq_vector(pdev, 0);
dev->flags |= controller->flags; dev->flags |= controller->flags;
if (controller->setup) { if (controller->setup) {
r = controller->setup(pdev, controller); r = controller->setup(pdev, controller);
if (r) if (r) {
pci_free_irq_vectors(pdev);
return r; return r;
}
} }
dev->functionality = controller->functionality | dev->functionality = controller->functionality |
...@@ -276,8 +291,10 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, ...@@ -276,8 +291,10 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
adap->nr = controller->bus_num; adap->nr = controller->bus_num;
r = i2c_dw_probe(dev); r = i2c_dw_probe(dev);
if (r) if (r) {
pci_free_irq_vectors(pdev);
return r; return r;
}
pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_use_autosuspend(&pdev->dev);
...@@ -296,6 +313,7 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev) ...@@ -296,6 +313,7 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev)
pm_runtime_get_noresume(&pdev->dev); pm_runtime_get_noresume(&pdev->dev);
i2c_del_adapter(&dev->adapter); i2c_del_adapter(&dev->adapter);
pci_free_irq_vectors(pdev);
} }
/* work with hotplug and coldplug */ /* work with hotplug and coldplug */
...@@ -331,6 +349,15 @@ static const struct pci_device_id i2_designware_pci_ids[] = { ...@@ -331,6 +349,15 @@ static const struct pci_device_id i2_designware_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x22C5), cherrytrail }, { PCI_VDEVICE(INTEL, 0x22C5), cherrytrail },
{ PCI_VDEVICE(INTEL, 0x22C6), cherrytrail }, { PCI_VDEVICE(INTEL, 0x22C6), cherrytrail },
{ PCI_VDEVICE(INTEL, 0x22C7), 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,} { 0,}
}; };
MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids); MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids);
......
...@@ -279,12 +279,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) ...@@ -279,12 +279,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, dev); platform_set_drvdata(pdev, dev);
dev->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); dev->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
if (IS_ERR(dev->rst)) { if (IS_ERR(dev->rst))
if (PTR_ERR(dev->rst) == -EPROBE_DEFER) return PTR_ERR(dev->rst);
return -EPROBE_DEFER;
} else { reset_control_deassert(dev->rst);
reset_control_deassert(dev->rst);
}
t = &dev->timings; t = &dev->timings;
if (pdata) if (pdata)
...@@ -346,8 +344,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) ...@@ -346,8 +344,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
/* Optional interface clock */ /* Optional interface clock */
dev->pclk = devm_clk_get_optional(&pdev->dev, "pclk"); dev->pclk = devm_clk_get_optional(&pdev->dev, "pclk");
if (IS_ERR(dev->pclk)) if (IS_ERR(dev->pclk)) {
return PTR_ERR(dev->pclk); ret = PTR_ERR(dev->pclk);
goto exit_reset;
}
dev->clk = devm_clk_get(&pdev->dev, NULL); dev->clk = devm_clk_get(&pdev->dev, NULL);
if (!i2c_dw_prepare_clk(dev, true)) { if (!i2c_dw_prepare_clk(dev, true)) {
...@@ -400,8 +400,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) ...@@ -400,8 +400,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
exit_probe: exit_probe:
dw_i2c_plat_pm_cleanup(dev); dw_i2c_plat_pm_cleanup(dev);
exit_reset: exit_reset:
if (!IS_ERR_OR_NULL(dev->rst)) reset_control_assert(dev->rst);
reset_control_assert(dev->rst);
return ret; return ret;
} }
...@@ -419,8 +418,7 @@ static int dw_i2c_plat_remove(struct platform_device *pdev) ...@@ -419,8 +418,7 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
dw_i2c_plat_pm_cleanup(dev); dw_i2c_plat_pm_cleanup(dev);
if (!IS_ERR_OR_NULL(dev->rst)) reset_control_assert(dev->rst);
reset_control_assert(dev->rst);
return 0; return 0;
} }
......
...@@ -791,9 +791,7 @@ static int exynos5_i2c_probe(struct platform_device *pdev) ...@@ -791,9 +791,7 @@ static int exynos5_i2c_probe(struct platform_device *pdev)
} }
ret = devm_request_irq(&pdev->dev, i2c->irq, exynos5_i2c_irq, ret = devm_request_irq(&pdev->dev, i2c->irq, exynos5_i2c_irq,
IRQF_NO_SUSPEND | IRQF_ONESHOT, IRQF_NO_SUSPEND, dev_name(&pdev->dev), i2c);
dev_name(&pdev->dev), i2c);
if (ret != 0) { if (ret != 0) {
dev_err(&pdev->dev, "cannot request HS-I2C IRQ %d\n", i2c->irq); dev_err(&pdev->dev, "cannot request HS-I2C IRQ %d\n", i2c->irq);
goto err_clk; goto err_clk;
......
...@@ -707,8 +707,10 @@ static int fsi_i2c_probe(struct device *dev) ...@@ -707,8 +707,10 @@ static int fsi_i2c_probe(struct device *dev)
continue; continue;
port = kzalloc(sizeof(*port), GFP_KERNEL); port = kzalloc(sizeof(*port), GFP_KERNEL);
if (!port) if (!port) {
of_node_put(np);
break; break;
}
port->master = i2c; port->master = i2c;
port->port = port_no; port->port = port_no;
......
...@@ -445,8 +445,7 @@ static int hix5hd2_i2c_probe(struct platform_device *pdev) ...@@ -445,8 +445,7 @@ static int hix5hd2_i2c_probe(struct platform_device *pdev)
hix5hd2_i2c_init(priv); hix5hd2_i2c_init(priv);
ret = devm_request_irq(&pdev->dev, irq, hix5hd2_i2c_irq, ret = devm_request_irq(&pdev->dev, irq, hix5hd2_i2c_irq,
IRQF_NO_SUSPEND | IRQF_ONESHOT, IRQF_NO_SUSPEND, dev_name(&pdev->dev), priv);
dev_name(&pdev->dev), priv);
if (ret != 0) { if (ret != 0) {
dev_err(&pdev->dev, "cannot request HS-I2C IRQ %d\n", irq); dev_err(&pdev->dev, "cannot request HS-I2C IRQ %d\n", irq);
goto err_clk; goto err_clk;
......
...@@ -292,7 +292,8 @@ struct i801_priv { ...@@ -292,7 +292,8 @@ struct i801_priv {
#define FEATURE_HOST_NOTIFY BIT(5) #define FEATURE_HOST_NOTIFY BIT(5)
/* Not really a feature, but it's convenient to handle it as such */ /* Not really a feature, but it's convenient to handle it as such */
#define FEATURE_IDF BIT(15) #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[] = { static const char *i801_feature_names[] = {
"SMBus PEC", "SMBus PEC",
...@@ -1500,57 +1501,23 @@ static inline unsigned int i801_get_adapter_class(struct i801_priv *priv) ...@@ -1500,57 +1501,23 @@ static inline unsigned int i801_get_adapter_class(struct i801_priv *priv)
} }
#endif #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", .name = "Intel PCH",
.version = 4, .version = 4,
}; };
static DEFINE_SPINLOCK(p2sb_spinlock); 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 *res;
struct resource tco_res[3], *res;
struct platform_device *pdev;
unsigned int devfn; unsigned int devfn;
u32 tco_base, tco_ctl;
u32 base_addr, ctrl_val;
u64 base64_addr; u64 base64_addr;
u32 base_addr;
u8 hidden; 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 * We must access the NO_REBOOT bit over the Primary to Sideband
* bridge (P2SB). The BIOS prevents the P2SB device from being * bridge (P2SB). The BIOS prevents the P2SB device from being
...@@ -1586,15 +1553,76 @@ static void i801_add_tco(struct i801_priv *priv) ...@@ -1586,15 +1553,76 @@ static void i801_add_tco(struct i801_priv *priv)
res->end = res->start + 3; res->end = res->start + 3;
res->flags = IORESOURCE_MEM; res->flags = IORESOURCE_MEM;
pdev = platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1, return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1,
tco_res, 3, &tco_platform_data, tco_res, 3, &spt_tco_platform_data,
sizeof(tco_platform_data)); sizeof(spt_tco_platform_data));
if (IS_ERR(pdev)) { }
dev_warn(&pci_dev->dev, "failed to create iTCO device\n");
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; return;
}
priv->tco_pdev = pdev; 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 #ifdef CONFIG_ACPI
...@@ -1704,13 +1732,21 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -1704,13 +1732,21 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
switch (dev->device) { switch (dev->device) {
case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_SMBUS:
case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_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_SMBUS:
case PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_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_DNV_SMBUS:
case PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_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_ICELAKE_LP_SMBUS:
case PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS: case PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS:
case PCI_DEVICE_ID_INTEL_ELKHART_LAKE_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) ...@@ -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_IRQ;
priv->features |= FEATURE_SMBUS_PEC; priv->features |= FEATURE_SMBUS_PEC;
priv->features |= FEATURE_BLOCK_BUFFER; priv->features |= FEATURE_BLOCK_BUFFER;
/* If we have ACPI based watchdog use that instead */ priv->features |= FEATURE_TCO_CNL;
if (!acpi_has_watchdog())
priv->features |= FEATURE_TCO;
priv->features |= FEATURE_HOST_NOTIFY; priv->features |= FEATURE_HOST_NOTIFY;
break; break;
...@@ -1921,8 +1955,7 @@ static int i801_suspend(struct device *dev) ...@@ -1921,8 +1955,7 @@ static int i801_suspend(struct device *dev)
static int i801_resume(struct device *dev) static int i801_resume(struct device *dev)
{ {
struct pci_dev *pci_dev = to_pci_dev(dev); struct i801_priv *priv = dev_get_drvdata(dev);
struct i801_priv *priv = pci_get_drvdata(pci_dev);
i801_enable_host_notify(&priv->adapter); i801_enable_host_notify(&priv->adapter);
......
// 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");
...@@ -545,7 +545,6 @@ MODULE_DEVICE_TABLE(of, lpi2c_imx_of_match); ...@@ -545,7 +545,6 @@ MODULE_DEVICE_TABLE(of, lpi2c_imx_of_match);
static int lpi2c_imx_probe(struct platform_device *pdev) static int lpi2c_imx_probe(struct platform_device *pdev)
{ {
struct lpi2c_imx_struct *lpi2c_imx; struct lpi2c_imx_struct *lpi2c_imx;
struct resource *res;
unsigned int temp; unsigned int temp;
int irq, ret; int irq, ret;
...@@ -553,8 +552,7 @@ static int lpi2c_imx_probe(struct platform_device *pdev) ...@@ -553,8 +552,7 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
if (!lpi2c_imx) if (!lpi2c_imx)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); lpi2c_imx->base = devm_platform_ioremap_resource(pdev, 0);
lpi2c_imx->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(lpi2c_imx->base)) if (IS_ERR(lpi2c_imx->base))
return PTR_ERR(lpi2c_imx->base); return PTR_ERR(lpi2c_imx->base);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
* *
*/ */
#include <linux/acpi.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -255,6 +256,12 @@ static const struct of_device_id i2c_imx_dt_ids[] = { ...@@ -255,6 +256,12 @@ static const struct of_device_id i2c_imx_dt_ids[] = {
}; };
MODULE_DEVICE_TABLE(of, 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) static inline int is_imx1_i2c(struct imx_i2c_struct *i2c_imx)
{ {
return i2c_imx->hwdata->devtype == IMX1_I2C; return i2c_imx->hwdata->devtype == IMX1_I2C;
...@@ -1048,14 +1055,13 @@ static const struct i2c_algorithm i2c_imx_algo = { ...@@ -1048,14 +1055,13 @@ static const struct i2c_algorithm i2c_imx_algo = {
static int i2c_imx_probe(struct platform_device *pdev) static int i2c_imx_probe(struct platform_device *pdev)
{ {
const struct of_device_id *of_id = of_match_device(i2c_imx_dt_ids,
&pdev->dev);
struct imx_i2c_struct *i2c_imx; struct imx_i2c_struct *i2c_imx;
struct resource *res; struct resource *res;
struct imxi2c_platform_data *pdata = dev_get_platdata(&pdev->dev); struct imxi2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
void __iomem *base; void __iomem *base;
int irq, ret; int irq, ret;
dma_addr_t phy_addr; dma_addr_t phy_addr;
const struct imx_i2c_hwdata *match;
dev_dbg(&pdev->dev, "<%s>\n", __func__); dev_dbg(&pdev->dev, "<%s>\n", __func__);
...@@ -1075,8 +1081,9 @@ static int i2c_imx_probe(struct platform_device *pdev) ...@@ -1075,8 +1081,9 @@ static int i2c_imx_probe(struct platform_device *pdev)
if (!i2c_imx) if (!i2c_imx)
return -ENOMEM; return -ENOMEM;
if (of_id) match = device_get_match_data(&pdev->dev);
i2c_imx->hwdata = of_id->data; if (match)
i2c_imx->hwdata = match;
else else
i2c_imx->hwdata = (struct imx_i2c_hwdata *) i2c_imx->hwdata = (struct imx_i2c_hwdata *)
platform_get_device_id(pdev)->driver_data; platform_get_device_id(pdev)->driver_data;
...@@ -1089,6 +1096,7 @@ static int i2c_imx_probe(struct platform_device *pdev) ...@@ -1089,6 +1096,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
i2c_imx->adapter.nr = pdev->id; i2c_imx->adapter.nr = pdev->id;
i2c_imx->adapter.dev.of_node = pdev->dev.of_node; i2c_imx->adapter.dev.of_node = pdev->dev.of_node;
i2c_imx->base = base; i2c_imx->base = base;
ACPI_COMPANION_SET(&i2c_imx->adapter.dev, ACPI_COMPANION(&pdev->dev));
/* Get I2C clock */ /* Get I2C clock */
i2c_imx->clk = devm_clk_get(&pdev->dev, NULL); i2c_imx->clk = devm_clk_get(&pdev->dev, NULL);
...@@ -1247,6 +1255,7 @@ static struct platform_driver i2c_imx_driver = { ...@@ -1247,6 +1255,7 @@ static struct platform_driver i2c_imx_driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.pm = &i2c_imx_pm_ops, .pm = &i2c_imx_pm_ops,
.of_match_table = i2c_imx_dt_ids, .of_match_table = i2c_imx_dt_ids,
.acpi_match_table = i2c_imx_acpi_ids,
}, },
.id_table = imx_i2c_devtype, .id_table = imx_i2c_devtype,
}; };
......
...@@ -781,8 +781,6 @@ static int ismt_dev_init(struct ismt_priv *priv) ...@@ -781,8 +781,6 @@ static int ismt_dev_init(struct ismt_priv *priv)
if (!priv->hw) if (!priv->hw)
return -ENOMEM; return -ENOMEM;
memset(priv->hw, 0, (ISMT_DESC_ENTRIES * sizeof(struct ismt_desc)));
priv->head = 0; priv->head = 0;
init_completion(&priv->cmp); init_completion(&priv->cmp);
......
...@@ -802,7 +802,6 @@ static int mxs_i2c_probe(struct platform_device *pdev) ...@@ -802,7 +802,6 @@ static int mxs_i2c_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct mxs_i2c_dev *i2c; struct mxs_i2c_dev *i2c;
struct i2c_adapter *adap; struct i2c_adapter *adap;
struct resource *res;
int err, irq; int err, irq;
i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL); i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
...@@ -814,8 +813,7 @@ static int mxs_i2c_probe(struct platform_device *pdev) ...@@ -814,8 +813,7 @@ static int mxs_i2c_probe(struct platform_device *pdev)
i2c->dev_type = device_id->driver_data; i2c->dev_type = device_id->driver_data;
} }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); i2c->regs = devm_platform_ioremap_resource(pdev, 0);
i2c->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(i2c->regs)) if (IS_ERR(i2c->regs))
return PTR_ERR(i2c->regs); return PTR_ERR(i2c->regs);
......
...@@ -703,8 +703,9 @@ static int ocores_i2c_probe(struct platform_device *pdev) ...@@ -703,8 +703,9 @@ static int ocores_i2c_probe(struct platform_device *pdev)
} }
if (ocores_algorithm.master_xfer != ocores_xfer_polling) { 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,
pdev->name, i2c); ocores_isr, 0,
pdev->name, i2c);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Cannot claim IRQ\n"); dev_err(&pdev->dev, "Cannot claim IRQ\n");
goto err_clk; goto err_clk;
......
...@@ -72,7 +72,8 @@ ...@@ -72,7 +72,8 @@
#define PIIX4_BLOCK_DATA 0x14 #define PIIX4_BLOCK_DATA 0x14
/* Multi-port constants */ /* Multi-port constants */
#define PIIX4_MAX_ADAPTERS 4 #define PIIX4_MAX_ADAPTERS 4
#define HUDSON2_MAIN_PORTS 2 /* HUDSON2, KERNCZ reserves ports 3, 4 */
/* SB800 constants */ /* SB800 constants */
#define SB800_PIIX4_SMB_IDX 0xcd6 #define SB800_PIIX4_SMB_IDX 0xcd6
...@@ -806,10 +807,12 @@ MODULE_DEVICE_TABLE (pci, piix4_ids); ...@@ -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_main_adapters[PIIX4_MAX_ADAPTERS];
static struct i2c_adapter *piix4_aux_adapter; static struct i2c_adapter *piix4_aux_adapter;
static int piix4_adapter_count;
static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
bool sb800_main, u8 port, bool notify_imc, 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_adapter *adap;
struct i2c_piix4_adapdata *adapdata; struct i2c_piix4_adapdata *adapdata;
...@@ -841,6 +844,12 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, ...@@ -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 */ /* set up the sysfs linkage to our parent device */
adap->dev.parent = &dev->dev; 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), snprintf(adap->name, sizeof(adap->name),
"SMBus PIIX4 adapter%s at %04x", name, smba); "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, ...@@ -865,8 +874,19 @@ static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba,
int port; int port;
int retval; 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, retval = piix4_add_adapter(dev, smba, true, port, notify_imc,
hw_port_nr,
piix4_main_port_names_sb800[port], piix4_main_port_names_sb800[port],
&piix4_main_adapters[port]); &piix4_main_adapters[port]);
if (retval < 0) if (retval < 0)
...@@ -937,8 +957,8 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -937,8 +957,8 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
return retval; return retval;
/* Try to register main SMBus adapter, give up if we can't */ /* Try to register main SMBus adapter, give up if we can't */
retval = piix4_add_adapter(dev, retval, false, 0, false, "", retval = piix4_add_adapter(dev, retval, false, 0, false, 0,
&piix4_main_adapters[0]); "", &piix4_main_adapters[0]);
if (retval < 0) if (retval < 0)
return retval; return retval;
} }
...@@ -964,7 +984,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -964,7 +984,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
if (retval > 0) { if (retval > 0) {
/* Try to add the aux adapter if it exists, /* Try to add the aux adapter if it exists,
* piix4_add_adapter will clean up if this fails */ * 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 : "", is_sb800 ? piix4_aux_port_name_sb800 : "",
&piix4_aux_adapter); &piix4_aux_adapter);
} }
...@@ -987,7 +1007,7 @@ static void piix4_adap_remove(struct i2c_adapter *adap) ...@@ -987,7 +1007,7 @@ static void piix4_adap_remove(struct i2c_adapter *adap)
static void piix4_remove(struct pci_dev *dev) static void piix4_remove(struct pci_dev *dev)
{ {
int port = PIIX4_MAX_ADAPTERS; int port = piix4_adapter_count;
while (--port >= 0) { while (--port >= 0) {
if (piix4_main_adapters[port]) { if (piix4_main_adapters[port]) {
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -465,9 +466,9 @@ static int sprd_i2c_clk_init(struct sprd_i2c *i2c_dev) ...@@ -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"); i2c_dev->clk = devm_clk_get(i2c_dev->dev, "enable");
if (IS_ERR(i2c_dev->clk)) { 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->adap.nr);
i2c_dev->clk = NULL; return PTR_ERR(i2c_dev->clk);
} }
return 0; return 0;
...@@ -477,7 +478,6 @@ static int sprd_i2c_probe(struct platform_device *pdev) ...@@ -477,7 +478,6 @@ static int sprd_i2c_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct sprd_i2c *i2c_dev; struct sprd_i2c *i2c_dev;
struct resource *res;
u32 prop; u32 prop;
int ret; int ret;
...@@ -487,8 +487,7 @@ static int sprd_i2c_probe(struct platform_device *pdev) ...@@ -487,8 +487,7 @@ static int sprd_i2c_probe(struct platform_device *pdev)
if (!i2c_dev) if (!i2c_dev)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); i2c_dev->base = devm_platform_ioremap_resource(pdev, 0);
i2c_dev->base = devm_ioremap_resource(dev, res);
if (IS_ERR(i2c_dev->base)) if (IS_ERR(i2c_dev->base))
return PTR_ERR(i2c_dev->base); return PTR_ERR(i2c_dev->base);
...@@ -520,7 +519,10 @@ static int sprd_i2c_probe(struct platform_device *pdev) ...@@ -520,7 +519,10 @@ static int sprd_i2c_probe(struct platform_device *pdev)
if (i2c_dev->bus_freq != 100000 && i2c_dev->bus_freq != 400000) if (i2c_dev->bus_freq != 100000 && i2c_dev->bus_freq != 400000)
return -EINVAL; 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); platform_set_drvdata(pdev, i2c_dev);
ret = clk_prepare_enable(i2c_dev->clk); ret = clk_prepare_enable(i2c_dev->clk);
...@@ -644,8 +646,7 @@ static struct platform_driver sprd_i2c_driver = { ...@@ -644,8 +646,7 @@ static struct platform_driver sprd_i2c_driver = {
}, },
}; };
static int sprd_i2c_init(void) module_platform_driver(sprd_i2c_driver);
{
return platform_driver_register(&sprd_i2c_driver); MODULE_DESCRIPTION("Spreadtrum I2C master controller driver");
} MODULE_LICENSE("GPL v2");
arch_initcall_sync(sprd_i2c_init);
...@@ -1809,7 +1809,7 @@ static u32 stm32f7_i2c_func(struct i2c_adapter *adap) ...@@ -1809,7 +1809,7 @@ static u32 stm32f7_i2c_func(struct i2c_adapter *adap)
I2C_FUNC_SMBUS_I2C_BLOCK; 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, .master_xfer = stm32f7_i2c_xfer,
.smbus_xfer = stm32f7_i2c_smbus_xfer, .smbus_xfer = stm32f7_i2c_smbus_xfer,
.functionality = stm32f7_i2c_func, .functionality = stm32f7_i2c_func,
......
...@@ -526,7 +526,7 @@ static const struct i2c_algorithm synquacer_i2c_algo = { ...@@ -526,7 +526,7 @@ static const struct i2c_algorithm synquacer_i2c_algo = {
.functionality = synquacer_i2c_functionality, .functionality = synquacer_i2c_functionality,
}; };
static struct i2c_adapter synquacer_i2c_ops = { static const struct i2c_adapter synquacer_i2c_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "synquacer_i2c-adapter", .name = "synquacer_i2c-adapter",
.algo = &synquacer_i2c_algo, .algo = &synquacer_i2c_algo,
......
...@@ -39,7 +39,7 @@ struct taos_data { ...@@ -39,7 +39,7 @@ struct taos_data {
}; };
/* TAOS TSL2550 EVM */ /* TAOS TSL2550 EVM */
static struct i2c_board_info tsl2550_info = { static const struct i2c_board_info tsl2550_info = {
I2C_BOARD_INFO("tsl2550", 0x39), I2C_BOARD_INFO("tsl2550", 0x39),
}; };
......
...@@ -636,7 +636,7 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev) ...@@ -636,7 +636,7 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
dvc_writel(i2c_dev, val, DVC_CTRL_REG1); 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); struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
int ret; int ret;
...@@ -665,7 +665,7 @@ static int tegra_i2c_runtime_resume(struct device *dev) ...@@ -665,7 +665,7 @@ static int tegra_i2c_runtime_resume(struct device *dev)
return 0; 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); 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) ...@@ -713,12 +713,6 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit)
u32 tsu_thd; u32 tsu_thd;
u8 tlow, thigh; 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); reset_control_assert(i2c_dev->rst);
udelay(2); udelay(2);
reset_control_deassert(i2c_dev->rst); reset_control_deassert(i2c_dev->rst);
...@@ -772,7 +766,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit) ...@@ -772,7 +766,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit)
if (err) { if (err) {
dev_err(i2c_dev->dev, dev_err(i2c_dev->dev,
"failed changing clock rate: %d\n", err); "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) ...@@ -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); err = tegra_i2c_flush_fifos(i2c_dev);
if (err) if (err)
goto err; return err;
if (i2c_dev->is_multimaster_mode && i2c_dev->hw->has_slcg_override_reg) 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); i2c_writel(i2c_dev, I2C_MST_CORE_CLKEN_OVR, I2C_CLKEN_OVERRIDE);
err = tegra_i2c_wait_for_config_load(i2c_dev); err = tegra_i2c_wait_for_config_load(i2c_dev);
if (err) if (err)
goto err; return err;
if (i2c_dev->irq_disabled) { if (i2c_dev->irq_disabled) {
i2c_dev->irq_disabled = false; i2c_dev->irq_disabled = false;
enable_irq(i2c_dev->irq); enable_irq(i2c_dev->irq);
} }
err: return 0;
pm_runtime_put(i2c_dev->dev);
return err;
} }
static int tegra_i2c_disable_packet_mode(struct tegra_i2c_dev *i2c_dev) static int tegra_i2c_disable_packet_mode(struct tegra_i2c_dev *i2c_dev)
...@@ -1616,12 +1608,14 @@ static int tegra_i2c_probe(struct platform_device *pdev) ...@@ -1616,12 +1608,14 @@ static int tegra_i2c_probe(struct platform_device *pdev)
} }
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
if (!pm_runtime_enabled(&pdev->dev)) { if (!pm_runtime_enabled(&pdev->dev))
ret = tegra_i2c_runtime_resume(&pdev->dev); ret = tegra_i2c_runtime_resume(&pdev->dev);
if (ret < 0) { else
dev_err(&pdev->dev, "runtime resume failed\n"); ret = pm_runtime_get_sync(i2c_dev->dev);
goto unprepare_div_clk;
} if (ret < 0) {
dev_err(&pdev->dev, "runtime resume failed\n");
goto unprepare_div_clk;
} }
if (i2c_dev->is_multimaster_mode) { if (i2c_dev->is_multimaster_mode) {
...@@ -1666,6 +1660,8 @@ static int tegra_i2c_probe(struct platform_device *pdev) ...@@ -1666,6 +1660,8 @@ static int tegra_i2c_probe(struct platform_device *pdev)
if (ret) if (ret)
goto release_dma; goto release_dma;
pm_runtime_put(&pdev->dev);
return 0; return 0;
release_dma: release_dma:
...@@ -1711,8 +1707,7 @@ static int tegra_i2c_remove(struct platform_device *pdev) ...@@ -1711,8 +1707,7 @@ static int tegra_i2c_remove(struct platform_device *pdev)
return 0; return 0;
} }
#ifdef CONFIG_PM_SLEEP static int __maybe_unused tegra_i2c_suspend(struct device *dev)
static int tegra_i2c_suspend(struct device *dev)
{ {
struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev); struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
...@@ -1721,38 +1716,41 @@ static int tegra_i2c_suspend(struct device *dev) ...@@ -1721,38 +1716,41 @@ static int tegra_i2c_suspend(struct device *dev)
return 0; 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); struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
int err; int err;
err = tegra_i2c_runtime_resume(dev);
if (err)
return err;
err = tegra_i2c_init(i2c_dev, false); err = tegra_i2c_init(i2c_dev, false);
if (err) if (err)
return err; return err;
err = tegra_i2c_runtime_suspend(dev);
if (err)
return err;
i2c_mark_adapter_resumed(&i2c_dev->adapter); i2c_mark_adapter_resumed(&i2c_dev->adapter);
return 0; return 0;
} }
static const struct dev_pm_ops tegra_i2c_pm = { 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, SET_RUNTIME_PM_OPS(tegra_i2c_runtime_suspend, tegra_i2c_runtime_resume,
NULL) NULL)
}; };
#define TEGRA_I2C_PM (&tegra_i2c_pm)
#else
#define TEGRA_I2C_PM NULL
#endif
static struct platform_driver tegra_i2c_driver = { static struct platform_driver tegra_i2c_driver = {
.probe = tegra_i2c_probe, .probe = tegra_i2c_probe,
.remove = tegra_i2c_remove, .remove = tegra_i2c_remove,
.driver = { .driver = {
.name = "tegra-i2c", .name = "tegra-i2c",
.of_match_table = tegra_i2c_of_match, .of_match_table = tegra_i2c_of_match,
.pm = TEGRA_I2C_PM, .pm = &tegra_i2c_pm,
}, },
}; };
......
...@@ -108,7 +108,6 @@ static void uniphier_fi2c_fill_txfifo(struct uniphier_fi2c_priv *priv, ...@@ -108,7 +108,6 @@ static void uniphier_fi2c_fill_txfifo(struct uniphier_fi2c_priv *priv,
if (fifo_space-- <= 0) if (fifo_space-- <= 0)
break; break;
dev_dbg(&priv->adap.dev, "write data: %02x\n", *priv->buf);
writel(*priv->buf++, priv->membase + UNIPHIER_FI2C_DTTX); writel(*priv->buf++, priv->membase + UNIPHIER_FI2C_DTTX);
priv->len--; priv->len--;
} }
...@@ -124,7 +123,6 @@ static void uniphier_fi2c_drain_rxfifo(struct uniphier_fi2c_priv *priv) ...@@ -124,7 +123,6 @@ static void uniphier_fi2c_drain_rxfifo(struct uniphier_fi2c_priv *priv)
break; break;
*priv->buf++ = readl(priv->membase + UNIPHIER_FI2C_DTRX); *priv->buf++ = readl(priv->membase + UNIPHIER_FI2C_DTRX);
dev_dbg(&priv->adap.dev, "read data: %02x\n", priv->buf[-1]);
priv->len--; priv->len--;
} }
} }
...@@ -142,8 +140,6 @@ static void uniphier_fi2c_clear_irqs(struct uniphier_fi2c_priv *priv, ...@@ -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) 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; priv->enabled_irqs |= UNIPHIER_FI2C_INT_STOP;
uniphier_fi2c_set_irqs(priv); uniphier_fi2c_set_irqs(priv);
writel(UNIPHIER_FI2C_CR_MST | UNIPHIER_FI2C_CR_STO, writel(UNIPHIER_FI2C_CR_MST | UNIPHIER_FI2C_CR_STO,
...@@ -160,21 +156,15 @@ static irqreturn_t uniphier_fi2c_interrupt(int irq, void *dev_id) ...@@ -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 = readl(priv->membase + UNIPHIER_FI2C_INT);
irq_status &= priv->enabled_irqs; 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) if (irq_status & UNIPHIER_FI2C_INT_STOP)
goto complete; goto complete;
if (unlikely(irq_status & UNIPHIER_FI2C_INT_AL)) { if (unlikely(irq_status & UNIPHIER_FI2C_INT_AL)) {
dev_dbg(&priv->adap.dev, "arbitration lost\n");
priv->error = -EAGAIN; priv->error = -EAGAIN;
goto complete; goto complete;
} }
if (unlikely(irq_status & UNIPHIER_FI2C_INT_NA)) { if (unlikely(irq_status & UNIPHIER_FI2C_INT_NA)) {
dev_dbg(&priv->adap.dev, "could not get ACK\n");
priv->error = -ENXIO; priv->error = -ENXIO;
if (priv->flags & UNIPHIER_FI2C_RD) { if (priv->flags & UNIPHIER_FI2C_RD) {
/* /*
...@@ -215,18 +205,14 @@ static irqreturn_t uniphier_fi2c_interrupt(int irq, void *dev_id) ...@@ -215,18 +205,14 @@ static irqreturn_t uniphier_fi2c_interrupt(int irq, void *dev_id)
if (unlikely(priv->flags & UNIPHIER_FI2C_MANUAL_NACK)) { if (unlikely(priv->flags & UNIPHIER_FI2C_MANUAL_NACK)) {
if (priv->len <= UNIPHIER_FI2C_FIFO_SIZE && if (priv->len <= UNIPHIER_FI2C_FIFO_SIZE &&
!(priv->flags & UNIPHIER_FI2C_BYTE_WISE)) { !(priv->flags & UNIPHIER_FI2C_BYTE_WISE)) {
dev_dbg(&priv->adap.dev,
"enable read byte count IRQ\n");
priv->enabled_irqs |= UNIPHIER_FI2C_INT_RB; priv->enabled_irqs |= UNIPHIER_FI2C_INT_RB;
uniphier_fi2c_set_irqs(priv); uniphier_fi2c_set_irqs(priv);
priv->flags |= UNIPHIER_FI2C_BYTE_WISE; priv->flags |= UNIPHIER_FI2C_BYTE_WISE;
} }
if (priv->len <= 1) { if (priv->len <= 1)
dev_dbg(&priv->adap.dev, "set NACK\n");
writel(UNIPHIER_FI2C_CR_MST | writel(UNIPHIER_FI2C_CR_MST |
UNIPHIER_FI2C_CR_NACK, UNIPHIER_FI2C_CR_NACK,
priv->membase + UNIPHIER_FI2C_CR); priv->membase + UNIPHIER_FI2C_CR);
}
} }
goto handled; goto handled;
...@@ -334,10 +320,6 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap, ...@@ -334,10 +320,6 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap,
bool is_read = msg->flags & I2C_M_RD; bool is_read = msg->flags & I2C_M_RD;
unsigned long time_left, flags; 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->len = msg->len;
priv->buf = msg->buf; priv->buf = msg->buf;
priv->enabled_irqs = UNIPHIER_FI2C_INT_FAULTS; priv->enabled_irqs = UNIPHIER_FI2C_INT_FAULTS;
...@@ -359,7 +341,6 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap, ...@@ -359,7 +341,6 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap,
else else
uniphier_fi2c_tx_init(priv, msg->addr, repeat); 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 * For a repeated START condition, writing a slave address to the FIFO
* kicks the controller. So, the UNIPHIER_FI2C_CR register should be * 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, ...@@ -383,7 +364,6 @@ static int uniphier_fi2c_master_xfer_one(struct i2c_adapter *adap,
uniphier_fi2c_recover(priv); uniphier_fi2c_recover(priv);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
dev_dbg(&adap->dev, "complete\n");
if (unlikely(priv->flags & UNIPHIER_FI2C_DEFER_STOP_COMP)) { if (unlikely(priv->flags & UNIPHIER_FI2C_DEFER_STOP_COMP)) {
u32 status; u32 status;
...@@ -538,7 +518,6 @@ static int uniphier_fi2c_probe(struct platform_device *pdev) ...@@ -538,7 +518,6 @@ static int uniphier_fi2c_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct uniphier_fi2c_priv *priv; struct uniphier_fi2c_priv *priv;
struct resource *regs;
u32 bus_speed; u32 bus_speed;
unsigned long clk_rate; unsigned long clk_rate;
int irq, ret; int irq, ret;
...@@ -547,8 +526,7 @@ static int uniphier_fi2c_probe(struct platform_device *pdev) ...@@ -547,8 +526,7 @@ static int uniphier_fi2c_probe(struct platform_device *pdev)
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->membase = devm_platform_ioremap_resource(pdev, 0);
priv->membase = devm_ioremap_resource(dev, regs);
if (IS_ERR(priv->membase)) if (IS_ERR(priv->membase))
return PTR_ERR(priv->membase); return PTR_ERR(priv->membase);
......
...@@ -71,7 +71,6 @@ static int uniphier_i2c_xfer_byte(struct i2c_adapter *adap, u32 txdata, ...@@ -71,7 +71,6 @@ static int uniphier_i2c_xfer_byte(struct i2c_adapter *adap, u32 txdata,
reinit_completion(&priv->comp); reinit_completion(&priv->comp);
txdata |= UNIPHIER_I2C_DTRM_IRQEN; txdata |= UNIPHIER_I2C_DTRM_IRQEN;
dev_dbg(&adap->dev, "write data: 0x%04x\n", txdata);
writel(txdata, priv->membase + UNIPHIER_I2C_DTRM); writel(txdata, priv->membase + UNIPHIER_I2C_DTRM);
time_left = wait_for_completion_timeout(&priv->comp, adap->timeout); 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, ...@@ -81,8 +80,6 @@ static int uniphier_i2c_xfer_byte(struct i2c_adapter *adap, u32 txdata,
} }
rxdata = readl(priv->membase + UNIPHIER_I2C_DREC); rxdata = readl(priv->membase + UNIPHIER_I2C_DREC);
dev_dbg(&adap->dev, "read data: 0x%04x\n", rxdata);
if (rxdatap) if (rxdatap)
*rxdatap = rxdata; *rxdatap = rxdata;
...@@ -98,14 +95,11 @@ static int uniphier_i2c_send_byte(struct i2c_adapter *adap, u32 txdata) ...@@ -98,14 +95,11 @@ static int uniphier_i2c_send_byte(struct i2c_adapter *adap, u32 txdata)
if (ret) if (ret)
return ret; return ret;
if (unlikely(rxdata & UNIPHIER_I2C_DREC_LAB)) { if (unlikely(rxdata & UNIPHIER_I2C_DREC_LAB))
dev_dbg(&adap->dev, "arbitration lost\n");
return -EAGAIN; return -EAGAIN;
}
if (unlikely(rxdata & UNIPHIER_I2C_DREC_LRB)) { if (unlikely(rxdata & UNIPHIER_I2C_DREC_LRB))
dev_dbg(&adap->dev, "could not get ACK\n");
return -ENXIO; return -ENXIO;
}
return 0; return 0;
} }
...@@ -115,7 +109,6 @@ static int uniphier_i2c_tx(struct i2c_adapter *adap, u16 addr, u16 len, ...@@ -115,7 +109,6 @@ static int uniphier_i2c_tx(struct i2c_adapter *adap, u16 addr, u16 len,
{ {
int ret; int ret;
dev_dbg(&adap->dev, "start condition\n");
ret = uniphier_i2c_send_byte(adap, addr << 1 | ret = uniphier_i2c_send_byte(adap, addr << 1 |
UNIPHIER_I2C_DTRM_STA | UNIPHIER_I2C_DTRM_STA |
UNIPHIER_I2C_DTRM_NACK); UNIPHIER_I2C_DTRM_NACK);
...@@ -137,7 +130,6 @@ static int uniphier_i2c_rx(struct i2c_adapter *adap, u16 addr, u16 len, ...@@ -137,7 +130,6 @@ static int uniphier_i2c_rx(struct i2c_adapter *adap, u16 addr, u16 len,
{ {
int ret; int ret;
dev_dbg(&adap->dev, "start condition\n");
ret = uniphier_i2c_send_byte(adap, addr << 1 | ret = uniphier_i2c_send_byte(adap, addr << 1 |
UNIPHIER_I2C_DTRM_STA | UNIPHIER_I2C_DTRM_STA |
UNIPHIER_I2C_DTRM_NACK | UNIPHIER_I2C_DTRM_NACK |
...@@ -161,7 +153,6 @@ static int uniphier_i2c_rx(struct i2c_adapter *adap, u16 addr, u16 len, ...@@ -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) 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 | return uniphier_i2c_send_byte(adap, UNIPHIER_I2C_DTRM_STO |
UNIPHIER_I2C_DTRM_NACK); UNIPHIER_I2C_DTRM_NACK);
} }
...@@ -173,9 +164,6 @@ static int uniphier_i2c_master_xfer_one(struct i2c_adapter *adap, ...@@ -173,9 +164,6 @@ static int uniphier_i2c_master_xfer_one(struct i2c_adapter *adap,
bool recovery = false; bool recovery = false;
int ret; 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) if (is_read)
ret = uniphier_i2c_rx(adap, msg->addr, msg->len, msg->buf); ret = uniphier_i2c_rx(adap, msg->addr, msg->len, msg->buf);
else else
...@@ -326,7 +314,6 @@ static int uniphier_i2c_probe(struct platform_device *pdev) ...@@ -326,7 +314,6 @@ static int uniphier_i2c_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct uniphier_i2c_priv *priv; struct uniphier_i2c_priv *priv;
struct resource *regs;
u32 bus_speed; u32 bus_speed;
unsigned long clk_rate; unsigned long clk_rate;
int irq, ret; int irq, ret;
...@@ -335,8 +322,7 @@ static int uniphier_i2c_probe(struct platform_device *pdev) ...@@ -335,8 +322,7 @@ static int uniphier_i2c_probe(struct platform_device *pdev)
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->membase = devm_platform_ioremap_resource(pdev, 0);
priv->membase = devm_ioremap_resource(dev, regs);
if (IS_ERR(priv->membase)) if (IS_ERR(priv->membase))
return PTR_ERR(priv->membase); return PTR_ERR(priv->membase);
......
...@@ -350,13 +350,11 @@ static int i2c_device_probe(struct device *dev) ...@@ -350,13 +350,11 @@ static int i2c_device_probe(struct device *dev)
return -ENODEV; return -ENODEV;
if (client->flags & I2C_CLIENT_WAKE) { if (client->flags & I2C_CLIENT_WAKE) {
int wakeirq = -ENOENT; int wakeirq;
if (dev->of_node) { wakeirq = of_irq_get_byname(dev->of_node, "wakeup");
wakeirq = of_irq_get_byname(dev->of_node, "wakeup"); if (wakeirq == -EPROBE_DEFER)
if (wakeirq == -EPROBE_DEFER) return wakeirq;
return wakeirq;
}
device_init_wakeup(&client->dev, true); device_init_wakeup(&client->dev, true);
...@@ -966,7 +964,7 @@ struct i2c_client *devm_i2c_new_dummy_device(struct device *dev, ...@@ -966,7 +964,7 @@ struct i2c_client *devm_i2c_new_dummy_device(struct device *dev,
EXPORT_SYMBOL_GPL(devm_i2c_new_dummy_device); 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 * and create the associated device
* @client: Handle to the primary client * @client: Handle to the primary client
* @name: Handle to specify which secondary address to get * @name: Handle to specify which secondary address to get
...@@ -985,9 +983,9 @@ EXPORT_SYMBOL_GPL(devm_i2c_new_dummy_device); ...@@ -985,9 +983,9 @@ EXPORT_SYMBOL_GPL(devm_i2c_new_dummy_device);
* cell whose "reg-names" value matches the slave name. * cell whose "reg-names" value matches the slave name.
* *
* This returns the new i2c client, which should be saved for later use with * 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, const char *name,
u16 default_addr) u16 default_addr)
{ {
...@@ -1002,9 +1000,9 @@ struct i2c_client *i2c_new_secondary_device(struct i2c_client *client, ...@@ -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); 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);
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
......
...@@ -11,6 +11,13 @@ ...@@ -11,6 +11,13 @@
* pointer, yet implementation is deferred until the need actually arises. * 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/i2c.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -21,12 +28,18 @@ ...@@ -21,12 +28,18 @@
struct eeprom_data { struct eeprom_data {
struct bin_attribute bin; struct bin_attribute bin;
bool first_write;
spinlock_t buffer_lock; spinlock_t buffer_lock;
u8 buffer_idx; u16 buffer_idx;
u16 address_mask;
u8 num_address_bytes;
u8 idx_write_cnt;
u8 buffer[]; 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, static int i2c_slave_eeprom_slave_cb(struct i2c_client *client,
enum i2c_slave_event event, u8 *val) enum i2c_slave_event event, u8 *val)
{ {
...@@ -34,12 +47,14 @@ static int i2c_slave_eeprom_slave_cb(struct i2c_client *client, ...@@ -34,12 +47,14 @@ static int i2c_slave_eeprom_slave_cb(struct i2c_client *client,
switch (event) { switch (event) {
case I2C_SLAVE_WRITE_RECEIVED: case I2C_SLAVE_WRITE_RECEIVED:
if (eeprom->first_write) { if (eeprom->idx_write_cnt < eeprom->num_address_bytes) {
eeprom->buffer_idx = *val; if (eeprom->idx_write_cnt == 0)
eeprom->first_write = false; eeprom->buffer_idx = 0;
eeprom->buffer_idx = *val | (eeprom->buffer_idx << 8);
eeprom->idx_write_cnt++;
} else { } else {
spin_lock(&eeprom->buffer_lock); 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); spin_unlock(&eeprom->buffer_lock);
} }
break; break;
...@@ -50,7 +65,7 @@ static int i2c_slave_eeprom_slave_cb(struct i2c_client *client, ...@@ -50,7 +65,7 @@ static int i2c_slave_eeprom_slave_cb(struct i2c_client *client,
/* fallthrough */ /* fallthrough */
case I2C_SLAVE_READ_REQUESTED: case I2C_SLAVE_READ_REQUESTED:
spin_lock(&eeprom->buffer_lock); 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); spin_unlock(&eeprom->buffer_lock);
/* /*
* Do not increment buffer_idx here, because we don't know if * 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, ...@@ -61,7 +76,7 @@ static int i2c_slave_eeprom_slave_cb(struct i2c_client *client,
case I2C_SLAVE_STOP: case I2C_SLAVE_STOP:
case I2C_SLAVE_WRITE_REQUESTED: case I2C_SLAVE_WRITE_REQUESTED:
eeprom->first_write = true; eeprom->idx_write_cnt = 0;
break; break;
default: default:
...@@ -105,13 +120,16 @@ static int i2c_slave_eeprom_probe(struct i2c_client *client, const struct i2c_de ...@@ -105,13 +120,16 @@ static int i2c_slave_eeprom_probe(struct i2c_client *client, const struct i2c_de
{ {
struct eeprom_data *eeprom; struct eeprom_data *eeprom;
int ret; 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); eeprom = devm_kzalloc(&client->dev, sizeof(struct eeprom_data) + size, GFP_KERNEL);
if (!eeprom) if (!eeprom)
return -ENOMEM; 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); spin_lock_init(&eeprom->buffer_lock);
i2c_set_clientdata(client, eeprom); i2c_set_clientdata(client, eeprom);
...@@ -146,7 +164,9 @@ static int i2c_slave_eeprom_remove(struct i2c_client *client) ...@@ -146,7 +164,9 @@ static int i2c_slave_eeprom_remove(struct i2c_client *client)
} }
static const struct i2c_device_id i2c_slave_eeprom_id[] = { 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); MODULE_DEVICE_TABLE(i2c, i2c_slave_eeprom_id);
......
...@@ -183,14 +183,14 @@ static int adv748x_initialise_clients(struct adv748x_state *state) ...@@ -183,14 +183,14 @@ static int adv748x_initialise_clients(struct adv748x_state *state)
int ret; int ret;
for (i = ADV748X_PAGE_DPLL; i < ADV748X_PAGE_MAX; ++i) { 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, state->client,
adv748x_default_addresses[i].name, adv748x_default_addresses[i].name,
adv748x_default_addresses[i].default_addr); 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); 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); ret = adv748x_configure_regmap(state, i);
......
...@@ -2862,10 +2862,8 @@ static void adv76xx_unregister_clients(struct adv76xx_state *state) ...@@ -2862,10 +2862,8 @@ static void adv76xx_unregister_clients(struct adv76xx_state *state)
{ {
unsigned int i; unsigned int i;
for (i = 1; i < ARRAY_SIZE(state->i2c_clients); ++i) { for (i = 1; i < ARRAY_SIZE(state->i2c_clients); ++i)
if (state->i2c_clients[i]) i2c_unregister_device(state->i2c_clients[i]);
i2c_unregister_device(state->i2c_clients[i]);
}
} }
static struct i2c_client *adv76xx_dummy_client(struct v4l2_subdev *sd, 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, ...@@ -2878,14 +2876,14 @@ static struct i2c_client *adv76xx_dummy_client(struct v4l2_subdev *sd,
struct i2c_client *new_client; struct i2c_client *new_client;
if (pdata && pdata->i2c_addresses[page]) 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]); pdata->i2c_addresses[page]);
else else
new_client = i2c_new_secondary_device(client, new_client = i2c_new_ancillary_device(client,
adv76xx_default_addresses[page].name, adv76xx_default_addresses[page].name,
adv76xx_default_addresses[page].default_addr); adv76xx_default_addresses[page].default_addr);
if (new_client) if (!IS_ERR(new_client))
io_write(sd, io_reg, new_client->addr << 1); io_write(sd, io_reg, new_client->addr << 1);
return new_client; return new_client;
...@@ -3516,15 +3514,19 @@ static int adv76xx_probe(struct i2c_client *client, ...@@ -3516,15 +3514,19 @@ static int adv76xx_probe(struct i2c_client *client,
} }
for (i = 1; i < ADV76XX_PAGE_MAX; ++i) { for (i = 1; i < ADV76XX_PAGE_MAX; ++i) {
struct i2c_client *dummy_client;
if (!(BIT(i) & state->info->page_mask)) if (!(BIT(i) & state->info->page_mask))
continue; continue;
state->i2c_clients[i] = adv76xx_dummy_client(sd, i); dummy_client = adv76xx_dummy_client(sd, i);
if (!state->i2c_clients[i]) { if (IS_ERR(dummy_client)) {
err = -EINVAL; err = PTR_ERR(dummy_client);
v4l2_err(sd, "failed to create i2c client %u\n", i); v4l2_err(sd, "failed to create i2c client %u\n", i);
goto err_i2c; goto err_i2c;
} }
state->i2c_clients[i] = dummy_client;
} }
INIT_DELAYED_WORK(&state->delayed_work_enable_hotplug, INIT_DELAYED_WORK(&state->delayed_work_enable_hotplug,
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h>
#include <linux/log2.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/property.h> #include <linux/property.h>
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
/* Includes */ /* Includes */
#include <linux/acpi.h> /* For ACPI support */ #include <linux/acpi.h> /* For ACPI support */
#include <linux/bits.h> /* For BIT() */
#include <linux/module.h> /* For module specific items */ #include <linux/module.h> /* For module specific items */
#include <linux/moduleparam.h> /* For new moduleparam's */ #include <linux/moduleparam.h> /* For new moduleparam's */
#include <linux/types.h> /* For standard types (like size_t) */ #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) ...@@ -215,6 +216,23 @@ static int update_no_reboot_bit_mem(void *priv, bool set)
return 0; 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, static void iTCO_wdt_no_reboot_bit_setup(struct iTCO_wdt_private *p,
struct itco_wdt_platform_data *pdata) struct itco_wdt_platform_data *pdata)
{ {
...@@ -224,7 +242,9 @@ static void iTCO_wdt_no_reboot_bit_setup(struct iTCO_wdt_private *p, ...@@ -224,7 +242,9 @@ static void iTCO_wdt_no_reboot_bit_setup(struct iTCO_wdt_private *p,
return; 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; p->update_no_reboot_bit = update_no_reboot_bit_mem;
else if (p->iTCO_version == 1) else if (p->iTCO_version == 1)
p->update_no_reboot_bit = update_no_reboot_bit_pci; p->update_no_reboot_bit = update_no_reboot_bit_pci;
...@@ -452,7 +472,8 @@ static int iTCO_wdt_probe(struct platform_device *pdev) ...@@ -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 * Get the Memory-Mapped GCS or PMC register, we need it for the
* NO_REBOOT flag (TCO v2 and v3). * 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, p->gcs_pmc_res = platform_get_resource(pdev,
IORESOURCE_MEM, IORESOURCE_MEM,
ICH_RES_MEM_GCS_PMC); ICH_RES_MEM_GCS_PMC);
...@@ -502,6 +523,7 @@ static int iTCO_wdt_probe(struct platform_device *pdev) ...@@ -502,6 +523,7 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
/* Clear out the (probably old) status */ /* Clear out the (probably old) status */
switch (p->iTCO_version) { switch (p->iTCO_version) {
case 6:
case 5: case 5:
case 4: case 4:
outw(0x0008, TCO1_STS(p)); /* Clear the Time Out Status bit */ outw(0x0008, TCO1_STS(p)); /* Clear the Time Out Status bit */
......
...@@ -473,7 +473,7 @@ extern struct i2c_client * ...@@ -473,7 +473,7 @@ extern struct i2c_client *
devm_i2c_new_dummy_device(struct device *dev, struct i2c_adapter *adap, u16 address); devm_i2c_new_dummy_device(struct device *dev, struct i2c_adapter *adap, u16 address);
extern struct i2c_client * extern struct i2c_client *
i2c_new_secondary_device(struct i2c_client *client, i2c_new_ancillary_device(struct i2c_client *client,
const char *name, const char *name,
u16 default_addr); u16 default_addr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment