Commit c77756d3 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'i2c-for-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c updates from Wolfram Sang:
 "Minor changes to the I2C core. Most changes are in drivers:

  The i801 and designware drivers received most of the changes,
  including refactorings and some additions.

  Recovery changes for the iMX and iMX-LPI2C are now utilizing the
  generic i2c support.

  The Cadence driver now supports system suspend and resume.

  The hisi, mpc, sh_mobile, and npcm drivers have undergone some
  cleanups and improvements. Meanwhile, Uwe continues his work on
  converting the "remove" callback to become a void function.

  The pca954x mux driver now supports additional configurations, such as
  isolating faulty channels and flushing stuck buses, among others.

  Support has been added for Renesas r8a779h0, i.MX95 LPI2C, and
  Microchip sam9x7. Meanwhile, Geert lays the groundwork for the
  upcoming R-Car Gen4"

* tag 'i2c-for-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (34 commits)
  i2c: sprd: Convert to platform remove callback returning void
  Documentation: i2c: Document that client auto-detection is a legacy mechanism
  i2c: remove redundant condition
  i2c: rcar: Prepare for the advent of ARCH_RCAR_GEN4
  i2c: imx-lpi2c: add generic GPIO recovery for LPI2C
  i2c: cadence: Add system suspend and resume PM support
  i2c: mpc: remove outdated macro
  i2c: mpc: use proper binding for transfer timeouts
  dt-bindings: i2c: mpc: use proper binding for transfer timeouts
  i2c: smbus: Prepare i2c_register_spd for usage on muxed segments
  i2c: constify the struct device_type usage
  i2c: designware: Implement generic polling mode code for Wangxun 10Gb NIC
  i2c: designware: Fix RX FIFO depth define on Wangxun 10Gb NIC
  i2c: designware: Move interrupt handling functions before i2c_dw_xfer()
  i2c: designware: Use accessors to DW_IC_INTR_MASK register
  i2c: designware: Do not enable interrupts shortly in polling mode
  i2c: designware: Uniform initialization flow for polling mode
  dt-bindings: i2c: at91: Add sam9x7 compatible string
  dt-bindings: i2c: imx-lpi2c: add i.MX95 LPI2C
  i2c: Remove redundant comparison in npcm_i2c_reg_slave
  ...
parents 4757c3c6 91962feb
......@@ -25,7 +25,9 @@ properties:
- atmel,sama5d2-i2c
- microchip,sam9x60-i2c
- items:
- const: microchip,sama7g5-i2c
- enum:
- microchip,sama7g5-i2c
- microchip,sam9x7-i2c
- const: microchip,sam9x60-i2c
reg:
......
......@@ -24,6 +24,7 @@ properties:
- fsl,imx8qm-lpi2c
- fsl,imx8ulp-lpi2c
- fsl,imx93-lpi2c
- fsl,imx95-lpi2c
- const: fsl,imx7ulp-lpi2c
reg:
......
......@@ -96,6 +96,6 @@ examples:
interrupts = <43 2>;
interrupt-parent = <&mpic>;
clock-frequency = <400000>;
i2c-scl-clk-low-timeout-us = <10000>;
i2c-transfer-timeout-us = <10000>;
};
...
......@@ -71,6 +71,23 @@ properties:
description: A voltage regulator supplying power to the chip. On PCA9846
the regulator supplies power to VDD2 (core logic) and optionally to VDD1.
maxim,isolate-stuck-channel:
type: boolean
description: Allows to use non faulty channels while a stuck channel is
isolated from the upstream bus. If not set all channels are isolated from
the upstream bus until the fault is cleared.
maxim,send-flush-out-sequence:
type: boolean
description: Send a flush-out sequence to stuck auxiliary buses
automatically after a stuck channel is being detected.
maxim,preconnection-wiggle-test-enable:
type: boolean
description: Send a STOP condition to the auxiliary buses when the switch
register activates a channel to detect a stuck high fault. On fault the
channel is isolated from the upstream bus.
required:
- compatible
- reg
......@@ -95,6 +112,19 @@ allOf:
"#interrupt-cells": false
interrupt-controller: false
- if:
not:
properties:
compatible:
contains:
enum:
- maxim,max7357
then:
properties:
maxim,isolate-stuck-channel: false
maxim,send-flush-out-sequence: false
maxim,preconnection-wiggle-test-enable: false
unevaluatedProperties: false
examples:
......
......@@ -53,6 +53,7 @@ properties:
- renesas,i2c-r8a779a0 # R-Car V3U
- renesas,i2c-r8a779f0 # R-Car S4-8
- renesas,i2c-r8a779g0 # R-Car V4H
- renesas,i2c-r8a779h0 # R-Car V4M
- const: renesas,rcar-gen4-i2c # R-Car Gen4
reg:
......
......@@ -48,10 +48,6 @@ driver model device node, and its I2C address.
.id_table = foo_idtable,
.probe = foo_probe,
.remove = foo_remove,
/* if device autodetection is needed: */
.class = I2C_CLASS_SOMETHING,
.detect = foo_detect,
.address_list = normal_i2c,
.shutdown = foo_shutdown, /* optional */
.command = foo_command, /* optional, deprecated */
......@@ -203,27 +199,8 @@ reference for later use.
Device Detection
----------------
Sometimes you do not know in advance which I2C devices are connected to
a given I2C bus. This is for example the case of hardware monitoring
devices on a PC's SMBus. In that case, you may want to let your driver
detect supported devices automatically. This is how the legacy model
was working, and is now available as an extension to the standard
driver model.
You simply have to define a detect callback which will attempt to
identify supported devices (returning 0 for supported ones and -ENODEV
for unsupported ones), a list of addresses to probe, and a device type
(or class) so that only I2C buses which may have that type of device
connected (and not otherwise enumerated) will be probed. For example,
a driver for a hardware monitoring chip for which auto-detection is
needed would set its class to I2C_CLASS_HWMON, and only I2C adapters
with a class including I2C_CLASS_HWMON would be probed by this driver.
Note that the absence of matching classes does not prevent the use of
a device of that type on the given I2C adapter. All it prevents is
auto-detection; explicit instantiation of devices is still possible.
Note that this mechanism is purely optional and not suitable for all
devices. You need some reliable way to identify the supported devices
The device detection mechanism comes with a number of disadvantages.
You need some reliable way to identify the supported devices
(typically using device-specific, dedicated identification registers),
otherwise misdetections are likely to occur and things can get wrong
quickly. Keep in mind that the I2C protocol doesn't include any
......@@ -231,9 +208,8 @@ standard way to detect the presence of a chip at a given address, let
alone a standard way to identify devices. Even worse is the lack of
semantics associated to bus transfers, which means that the same
transfer can be seen as a read operation by a chip and as a write
operation by another chip. For these reasons, explicit device
instantiation should always be preferred to auto-detection where
possible.
operation by another chip. For these reasons, device detection is
considered a legacy mechanism and shouldn't be used in new code.
Device Deletion
......
......@@ -1235,7 +1235,7 @@ config I2C_RCAR
depends on ARCH_RENESAS || COMPILE_TEST
select I2C_SLAVE
select I2C_SMBUS
select RESET_CONTROLLER if ARCH_RCAR_GEN3
select RESET_CONTROLLER if ARCH_RCAR_GEN3 || ARCH_RCAR_GEN4
help
If you say yes to this option, support will be included for the
R-Car I2C controller.
......
......@@ -1176,6 +1176,18 @@ static int __maybe_unused cdns_i2c_runtime_suspend(struct device *dev)
return 0;
}
static int __maybe_unused cdns_i2c_suspend(struct device *dev)
{
struct cdns_i2c *xi2c = dev_get_drvdata(dev);
i2c_mark_adapter_suspended(&xi2c->adap);
if (!pm_runtime_status_suspended(dev))
return cdns_i2c_runtime_suspend(dev);
return 0;
}
/**
* cdns_i2c_init - Controller initialisation
* @id: Device private data structure
......@@ -1219,7 +1231,28 @@ static int __maybe_unused cdns_i2c_runtime_resume(struct device *dev)
return 0;
}
static int __maybe_unused cdns_i2c_resume(struct device *dev)
{
struct cdns_i2c *xi2c = dev_get_drvdata(dev);
int err;
err = cdns_i2c_runtime_resume(dev);
if (err)
return err;
if (pm_runtime_status_suspended(dev)) {
err = cdns_i2c_runtime_suspend(dev);
if (err)
return err;
}
i2c_mark_adapter_resumed(&xi2c->adap);
return 0;
}
static const struct dev_pm_ops cdns_i2c_dev_pm_ops = {
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(cdns_i2c_suspend, cdns_i2c_resume)
SET_RUNTIME_PM_OPS(cdns_i2c_runtime_suspend,
cdns_i2c_runtime_resume, NULL)
};
......
......@@ -648,7 +648,7 @@ void i2c_dw_disable(struct dw_i2c_dev *dev)
__i2c_dw_disable(dev);
/* Disable all interrupts */
regmap_write(dev->map, DW_IC_INTR_MASK, 0);
__i2c_dw_write_intr_mask(dev, 0);
regmap_read(dev->map, DW_IC_CLR_INTR, &dummy);
i2c_dw_release_lock(dev);
......
......@@ -212,6 +212,7 @@ struct reset_control;
* @msg_err: error status of the current transfer
* @status: i2c master status, one of STATUS_*
* @abort_source: copy of the TX_ABRT_SOURCE register
* @sw_mask: SW mask of DW_IC_INTR_MASK used in polling mode
* @irq: interrupt number for the i2c master
* @flags: platform specific flags like type of IO accessors or model
* @adapter: i2c subsystem adapter node
......@@ -270,6 +271,7 @@ struct dw_i2c_dev {
int msg_err;
unsigned int status;
unsigned int abort_source;
unsigned int sw_mask;
int irq;
u32 flags;
struct i2c_adapter adapter;
......@@ -303,6 +305,7 @@ struct dw_i2c_dev {
#define ACCESS_INTR_MASK BIT(0)
#define ACCESS_NO_IRQ_SUSPEND BIT(1)
#define ARBITRATION_SEMAPHORE BIT(2)
#define ACCESS_POLLING BIT(3)
#define MODEL_MSCC_OCELOT BIT(8)
#define MODEL_BAIKAL_BT1 BIT(9)
......@@ -318,7 +321,7 @@ struct dw_i2c_dev {
#define AMD_UCSI_INTR_EN 0xd
#define TXGBE_TX_FIFO_DEPTH 4
#define TXGBE_RX_FIFO_DEPTH 0
#define TXGBE_RX_FIFO_DEPTH 1
struct i2c_dw_semaphore_callbacks {
int (*probe)(struct dw_i2c_dev *dev);
......@@ -351,6 +354,24 @@ static inline void __i2c_dw_disable_nowait(struct dw_i2c_dev *dev)
dev->status &= ~STATUS_ACTIVE;
}
static inline void __i2c_dw_write_intr_mask(struct dw_i2c_dev *dev,
unsigned int intr_mask)
{
unsigned int val = dev->flags & ACCESS_POLLING ? 0 : intr_mask;
regmap_write(dev->map, DW_IC_INTR_MASK, val);
dev->sw_mask = intr_mask;
}
static inline void __i2c_dw_read_intr_mask(struct dw_i2c_dev *dev,
unsigned int *intr_mask)
{
if (!(dev->flags & ACCESS_POLLING))
regmap_read(dev->map, DW_IC_INTR_MASK, intr_mask);
else
*intr_mask = dev->sw_mask;
}
void __i2c_dw_disable(struct dw_i2c_dev *dev);
extern void i2c_dw_configure_master(struct dw_i2c_dev *dev);
......
This diff is collapsed.
......@@ -154,7 +154,7 @@ static int navi_amd_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
{
struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev);
dev->flags |= MODEL_AMD_NAVI_GPU;
dev->flags |= MODEL_AMD_NAVI_GPU | ACCESS_POLLING;
dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ;
return 0;
}
......
......@@ -290,7 +290,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
dev->flags = (uintptr_t)device_get_match_data(&pdev->dev);
if (device_property_present(&pdev->dev, "wx,i2c-snps-model"))
dev->flags = MODEL_WANGXUN_SP;
dev->flags = MODEL_WANGXUN_SP | ACCESS_POLLING;
dev->dev = &pdev->dev;
dev->irq = irq;
......
......@@ -57,6 +57,8 @@
#define HISI_I2C_FS_SPK_LEN_CNT GENMASK(7, 0)
#define HISI_I2C_HS_SPK_LEN 0x003c
#define HISI_I2C_HS_SPK_LEN_CNT GENMASK(7, 0)
#define HISI_I2C_TX_INT_CLR 0x0040
#define HISI_I2C_TX_AEMPTY_INT BIT(0)
#define HISI_I2C_INT_MSTAT 0x0044
#define HISI_I2C_INT_CLR 0x0048
#define HISI_I2C_INT_MASK 0x004C
......@@ -124,6 +126,11 @@ static void hisi_i2c_clear_int(struct hisi_i2c_controller *ctlr, u32 mask)
writel_relaxed(mask, ctlr->iobase + HISI_I2C_INT_CLR);
}
static void hisi_i2c_clear_tx_int(struct hisi_i2c_controller *ctlr, u32 mask)
{
writel_relaxed(mask, ctlr->iobase + HISI_I2C_TX_INT_CLR);
}
static void hisi_i2c_handle_errors(struct hisi_i2c_controller *ctlr)
{
u32 int_err = ctlr->xfer_err, reg;
......@@ -168,6 +175,7 @@ static int hisi_i2c_start_xfer(struct hisi_i2c_controller *ctlr)
writel(reg, ctlr->iobase + HISI_I2C_FIFO_CTRL);
hisi_i2c_clear_int(ctlr, HISI_I2C_INT_ALL);
hisi_i2c_clear_tx_int(ctlr, HISI_I2C_TX_AEMPTY_INT);
hisi_i2c_enable_int(ctlr, HISI_I2C_INT_ALL);
return 0;
......@@ -266,7 +274,7 @@ static int hisi_i2c_read_rx_fifo(struct hisi_i2c_controller *ctlr)
static void hisi_i2c_xfer_msg(struct hisi_i2c_controller *ctlr)
{
int max_write = HISI_I2C_TX_FIFO_DEPTH;
int max_write = HISI_I2C_TX_FIFO_DEPTH - HISI_I2C_TX_F_AE_THRESH;
bool need_restart = false, last_msg;
struct i2c_msg *cur_msg;
u32 cmd, fifo_state;
......@@ -323,6 +331,8 @@ static void hisi_i2c_xfer_msg(struct hisi_i2c_controller *ctlr)
*/
if (ctlr->msg_tx_idx == ctlr->msg_num)
hisi_i2c_disable_int(ctlr, HISI_I2C_INT_TX_EMPTY);
hisi_i2c_clear_tx_int(ctlr, HISI_I2C_TX_AEMPTY_INT);
}
static irqreturn_t hisi_i2c_irq(int irq, void *context)
......@@ -363,6 +373,7 @@ static irqreturn_t hisi_i2c_irq(int irq, void *context)
if (int_stat & HISI_I2C_INT_TRANS_CPLT) {
hisi_i2c_disable_int(ctlr, HISI_I2C_INT_ALL);
hisi_i2c_clear_int(ctlr, HISI_I2C_INT_ALL);
hisi_i2c_clear_tx_int(ctlr, HISI_I2C_TX_AEMPTY_INT);
complete(ctlr->completion);
}
......
This diff is collapsed.
......@@ -106,6 +106,7 @@ struct lpi2c_imx_struct {
unsigned int txfifosize;
unsigned int rxfifosize;
enum lpi2c_imx_mode mode;
struct i2c_bus_recovery_info rinfo;
};
static void lpi2c_imx_intctrl(struct lpi2c_imx_struct *lpi2c_imx,
......@@ -133,6 +134,8 @@ static int lpi2c_imx_bus_busy(struct lpi2c_imx_struct *lpi2c_imx)
if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
dev_dbg(&lpi2c_imx->adapter.dev, "bus not work\n");
if (lpi2c_imx->adapter.bus_recovery_info)
i2c_recover_bus(&lpi2c_imx->adapter);
return -ETIMEDOUT;
}
schedule();
......@@ -190,6 +193,8 @@ static void lpi2c_imx_stop(struct lpi2c_imx_struct *lpi2c_imx)
if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
dev_dbg(&lpi2c_imx->adapter.dev, "stop timeout\n");
if (lpi2c_imx->adapter.bus_recovery_info)
i2c_recover_bus(&lpi2c_imx->adapter);
break;
}
schedule();
......@@ -325,6 +330,8 @@ static int lpi2c_imx_txfifo_empty(struct lpi2c_imx_struct *lpi2c_imx)
if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
dev_dbg(&lpi2c_imx->adapter.dev, "txfifo empty timeout\n");
if (lpi2c_imx->adapter.bus_recovery_info)
i2c_recover_bus(&lpi2c_imx->adapter);
return -ETIMEDOUT;
}
schedule();
......@@ -526,6 +533,20 @@ static irqreturn_t lpi2c_imx_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
static int lpi2c_imx_init_recovery_info(struct lpi2c_imx_struct *lpi2c_imx,
struct platform_device *pdev)
{
struct i2c_bus_recovery_info *bri = &lpi2c_imx->rinfo;
bri->pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(bri->pinctrl))
return PTR_ERR(bri->pinctrl);
lpi2c_imx->adapter.bus_recovery_info = bri;
return 0;
}
static u32 lpi2c_imx_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
......@@ -600,6 +621,12 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
lpi2c_imx->txfifosize = 1 << (temp & 0x0f);
lpi2c_imx->rxfifosize = 1 << ((temp >> 8) & 0x0f);
/* Init optional bus recovery function */
ret = lpi2c_imx_init_recovery_info(lpi2c_imx, pdev);
/* Give it another chance if pinctrl used is not ready yet */
if (ret == -EPROBE_DEFER)
goto rpm_disable;
ret = i2c_add_adapter(&lpi2c_imx->adapter);
if (ret)
goto rpm_disable;
......
......@@ -212,10 +212,6 @@ struct imx_i2c_struct {
const struct imx_i2c_hwdata *hwdata;
struct i2c_bus_recovery_info rinfo;
struct pinctrl *pinctrl;
struct pinctrl_state *pinctrl_pins_default;
struct pinctrl_state *pinctrl_pins_gpio;
struct imx_i2c_dma *dma;
struct i2c_client *slave;
enum i2c_slave_event last_slave_event;
......@@ -1362,24 +1358,6 @@ static int i2c_imx_xfer_atomic(struct i2c_adapter *adapter,
return result;
}
static void i2c_imx_prepare_recovery(struct i2c_adapter *adap)
{
struct imx_i2c_struct *i2c_imx;
i2c_imx = container_of(adap, struct imx_i2c_struct, adapter);
pinctrl_select_state(i2c_imx->pinctrl, i2c_imx->pinctrl_pins_gpio);
}
static void i2c_imx_unprepare_recovery(struct i2c_adapter *adap)
{
struct imx_i2c_struct *i2c_imx;
i2c_imx = container_of(adap, struct imx_i2c_struct, adapter);
pinctrl_select_state(i2c_imx->pinctrl, i2c_imx->pinctrl_pins_default);
}
/*
* We switch SCL and SDA to their GPIO function and do some bitbanging
* for bus recovery. These alternative pinmux settings can be
......@@ -1390,43 +1368,13 @@ static void i2c_imx_unprepare_recovery(struct i2c_adapter *adap)
static int i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
struct platform_device *pdev)
{
struct i2c_bus_recovery_info *rinfo = &i2c_imx->rinfo;
i2c_imx->pinctrl = devm_pinctrl_get(&pdev->dev);
if (!i2c_imx->pinctrl) {
dev_info(&pdev->dev, "pinctrl unavailable, bus recovery not supported\n");
return 0;
}
if (IS_ERR(i2c_imx->pinctrl)) {
dev_info(&pdev->dev, "can't get pinctrl, bus recovery not supported\n");
return PTR_ERR(i2c_imx->pinctrl);
}
i2c_imx->pinctrl_pins_default = pinctrl_lookup_state(i2c_imx->pinctrl,
PINCTRL_STATE_DEFAULT);
i2c_imx->pinctrl_pins_gpio = pinctrl_lookup_state(i2c_imx->pinctrl,
"gpio");
rinfo->sda_gpiod = devm_gpiod_get_optional(&pdev->dev, "sda", GPIOD_IN);
rinfo->scl_gpiod = devm_gpiod_get(&pdev->dev, "scl", GPIOD_OUT_HIGH_OPEN_DRAIN);
if (PTR_ERR(rinfo->sda_gpiod) == -EPROBE_DEFER ||
PTR_ERR(rinfo->scl_gpiod) == -EPROBE_DEFER) {
return -EPROBE_DEFER;
} else if (IS_ERR(rinfo->sda_gpiod) ||
IS_ERR(rinfo->scl_gpiod) ||
IS_ERR(i2c_imx->pinctrl_pins_default) ||
IS_ERR(i2c_imx->pinctrl_pins_gpio)) {
dev_dbg(&pdev->dev, "recovery information incomplete\n");
return 0;
}
struct i2c_bus_recovery_info *bri = &i2c_imx->rinfo;
dev_dbg(&pdev->dev, "using scl%s for recovery\n",
rinfo->sda_gpiod ? ",sda" : "");
bri->pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(bri->pinctrl))
return PTR_ERR(bri->pinctrl);
rinfo->prepare_recovery = i2c_imx_prepare_recovery;
rinfo->unprepare_recovery = i2c_imx_unprepare_recovery;
rinfo->recover_bus = i2c_generic_scl_recovery;
i2c_imx->adapter.bus_recovery_info = rinfo;
i2c_imx->adapter.bus_recovery_info = bri;
return 0;
}
......
......@@ -30,8 +30,6 @@
#include <asm/mpc85xx.h>
#include <sysdev/fsl_soc.h>
#define DRV_NAME "mpc-i2c"
#define MPC_I2C_CLOCK_LEGACY 0
#define MPC_I2C_CLOCK_PRESERVE (~0U)
......@@ -844,14 +842,14 @@ static int fsl_i2c_probe(struct platform_device *op)
mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock);
}
/*
* "fsl,timeout" has been marked as deprecated and, to maintain
* backward compatibility, we will only look for it if
* "i2c-scl-clk-low-timeout-us" is not present.
*/
/* Sadly, we have to support two deprecated bindings here */
result = of_property_read_u32(op->dev.of_node,
"i2c-scl-clk-low-timeout-us",
"i2c-transfer-timeout-us",
&mpc_ops.timeout);
if (result == -EINVAL)
result = of_property_read_u32(op->dev.of_node,
"i2c-scl-clk-low-timeout-us",
&mpc_ops.timeout);
if (result == -EINVAL)
result = of_property_read_u32(op->dev.of_node,
"fsl,timeout", &mpc_ops.timeout);
......@@ -960,7 +958,7 @@ static struct platform_driver mpc_i2c_driver = {
.probe = fsl_i2c_probe,
.remove_new = fsl_i2c_remove,
.driver = {
.name = DRV_NAME,
.name = "mpc-i2c",
.of_match_table = mpc_i2c_of_match,
.pm = &mpc_i2c_pm_ops,
},
......
......@@ -1264,9 +1264,6 @@ static int npcm_i2c_reg_slave(struct i2c_client *client)
bus->slave = client;
if (!bus->slave)
return -EINVAL;
if (client->flags & I2C_CLIENT_TEN)
return -EAFNOSUPPORT;
......
......@@ -773,7 +773,7 @@ static int sh_mobile_i2c_r8a7740_workaround(struct sh_mobile_i2c_data *pd)
iic_wr(pd, ICCR, ICCR_TRS);
udelay(10);
return sh_mobile_i2c_init(pd);
return sh_mobile_i2c_v2_init(pd);
}
static const struct sh_mobile_dt_config default_dt_config = {
......@@ -782,11 +782,6 @@ static const struct sh_mobile_dt_config default_dt_config = {
};
static const struct sh_mobile_dt_config fast_clock_dt_config = {
.clks_per_count = 2,
.setup = sh_mobile_i2c_init,
};
static const struct sh_mobile_dt_config v2_freq_calc_dt_config = {
.clks_per_count = 2,
.setup = sh_mobile_i2c_v2_init,
};
......@@ -799,17 +794,17 @@ static const struct sh_mobile_dt_config r8a7740_dt_config = {
static const struct of_device_id sh_mobile_i2c_dt_ids[] = {
{ .compatible = "renesas,iic-r8a73a4", .data = &fast_clock_dt_config },
{ .compatible = "renesas,iic-r8a7740", .data = &r8a7740_dt_config },
{ .compatible = "renesas,iic-r8a774c0", .data = &v2_freq_calc_dt_config },
{ .compatible = "renesas,iic-r8a7790", .data = &v2_freq_calc_dt_config },
{ .compatible = "renesas,iic-r8a7791", .data = &v2_freq_calc_dt_config },
{ .compatible = "renesas,iic-r8a7792", .data = &v2_freq_calc_dt_config },
{ .compatible = "renesas,iic-r8a7793", .data = &v2_freq_calc_dt_config },
{ .compatible = "renesas,iic-r8a7794", .data = &v2_freq_calc_dt_config },
{ .compatible = "renesas,iic-r8a7795", .data = &v2_freq_calc_dt_config },
{ .compatible = "renesas,iic-r8a77990", .data = &v2_freq_calc_dt_config },
{ .compatible = "renesas,iic-r8a774c0", .data = &fast_clock_dt_config },
{ .compatible = "renesas,iic-r8a7790", .data = &fast_clock_dt_config },
{ .compatible = "renesas,iic-r8a7791", .data = &fast_clock_dt_config },
{ .compatible = "renesas,iic-r8a7792", .data = &fast_clock_dt_config },
{ .compatible = "renesas,iic-r8a7793", .data = &fast_clock_dt_config },
{ .compatible = "renesas,iic-r8a7794", .data = &fast_clock_dt_config },
{ .compatible = "renesas,iic-r8a7795", .data = &fast_clock_dt_config },
{ .compatible = "renesas,iic-r8a77990", .data = &fast_clock_dt_config },
{ .compatible = "renesas,iic-sh73a0", .data = &fast_clock_dt_config },
{ .compatible = "renesas,rcar-gen2-iic", .data = &v2_freq_calc_dt_config },
{ .compatible = "renesas,rcar-gen3-iic", .data = &v2_freq_calc_dt_config },
{ .compatible = "renesas,rcar-gen2-iic", .data = &fast_clock_dt_config },
{ .compatible = "renesas,rcar-gen3-iic", .data = &fast_clock_dt_config },
{ .compatible = "renesas,rmobile-iic", .data = &default_dt_config },
{},
};
......
......@@ -570,7 +570,7 @@ static int sprd_i2c_probe(struct platform_device *pdev)
return ret;
}
static int sprd_i2c_remove(struct platform_device *pdev)
static void sprd_i2c_remove(struct platform_device *pdev)
{
struct sprd_i2c *i2c_dev = platform_get_drvdata(pdev);
int ret;
......@@ -586,8 +586,6 @@ static int sprd_i2c_remove(struct platform_device *pdev)
pm_runtime_put_noidle(i2c_dev->dev);
pm_runtime_disable(i2c_dev->dev);
return 0;
}
static int __maybe_unused sprd_i2c_suspend_noirq(struct device *dev)
......@@ -645,7 +643,7 @@ MODULE_DEVICE_TABLE(of, sprd_i2c_of_match);
static struct platform_driver sprd_i2c_driver = {
.probe = sprd_i2c_probe,
.remove = sprd_i2c_remove,
.remove_new = sprd_i2c_remove,
.driver = {
.name = "sprd-i2c",
.of_match_table = sprd_i2c_of_match,
......
......@@ -701,7 +701,7 @@ const struct bus_type i2c_bus_type = {
};
EXPORT_SYMBOL_GPL(i2c_bus_type);
struct device_type i2c_client_type = {
const struct device_type i2c_client_type = {
.groups = i2c_dev_groups,
.uevent = i2c_device_uevent,
.release = i2c_client_dev_release,
......@@ -1343,7 +1343,7 @@ static struct attribute *i2c_adapter_attrs[] = {
};
ATTRIBUTE_GROUPS(i2c_adapter);
struct device_type i2c_adapter_type = {
const struct device_type i2c_adapter_type = {
.groups = i2c_adapter_groups,
.release = i2c_adapter_dev_release,
};
......
......@@ -351,13 +351,18 @@ void i2c_register_spd(struct i2c_adapter *adap)
if (!dimm_count)
return;
dev_info(&adap->dev, "%d/%d memory slots populated (from DMI)\n",
dimm_count, slot_count);
if (slot_count > 8) {
dev_warn(&adap->dev,
"Systems with more than 8 memory slots not supported yet, not instantiating SPD\n");
return;
/*
* If we're a child adapter on a muxed segment, then limit slots to 8,
* as this is the max number of SPD EEPROMs that can be addressed per bus.
*/
if (i2c_parent_is_i2c_adapter(adap)) {
slot_count = 8;
} else {
if (slot_count > 8) {
dev_warn(&adap->dev,
"More than 8 memory slots on a single bus, contact i801 maintainer to add missing mux config\n");
return;
}
}
/*
......
......@@ -57,6 +57,20 @@
#define PCA954X_IRQ_OFFSET 4
/*
* MAX7357's configuration register is writeable after POR, but
* can be locked by setting the basic mode bit. MAX7358 configuration
* register is locked by default and needs to be unlocked first.
* The configuration register holds the following settings:
*/
#define MAX7357_CONF_INT_ENABLE BIT(0)
#define MAX7357_CONF_FLUSH_OUT BIT(1)
#define MAX7357_CONF_RELEASE_INT BIT(2)
#define MAX7357_CONF_DISCON_SINGLE_CHAN BIT(4)
#define MAX7357_CONF_PRECONNECT_TEST BIT(7)
#define MAX7357_POR_DEFAULT_CONF MAX7357_CONF_INT_ENABLE
enum pca_type {
max_7356,
max_7357,
......@@ -470,7 +484,34 @@ static int pca954x_init(struct i2c_client *client, struct pca954x *data)
else
data->last_chan = 0; /* Disconnect multiplexer */
ret = i2c_smbus_write_byte(client, data->last_chan);
if (device_is_compatible(&client->dev, "maxim,max7357")) {
if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) {
u8 conf = MAX7357_POR_DEFAULT_CONF;
/*
* The interrupt signal is shared with the reset pin. Release the
* interrupt after 1.6 seconds to allow using the pin as reset.
*/
conf |= MAX7357_CONF_RELEASE_INT;
if (device_property_read_bool(&client->dev, "maxim,isolate-stuck-channel"))
conf |= MAX7357_CONF_DISCON_SINGLE_CHAN;
if (device_property_read_bool(&client->dev,
"maxim,send-flush-out-sequence"))
conf |= MAX7357_CONF_FLUSH_OUT;
if (device_property_read_bool(&client->dev,
"maxim,preconnection-wiggle-test-enable"))
conf |= MAX7357_CONF_PRECONNECT_TEST;
ret = i2c_smbus_write_byte_data(client, data->last_chan, conf);
} else {
dev_warn(&client->dev, "Write byte data not supported."
"Cannot enable enhanced mode features\n");
ret = i2c_smbus_write_byte(client, data->last_chan);
}
} else {
ret = i2c_smbus_write_byte(client, data->last_chan);
}
if (ret < 0)
data->last_chan = 0;
......
......@@ -24,8 +24,8 @@
#include <uapi/linux/i2c.h>
extern const struct bus_type i2c_bus_type;
extern struct device_type i2c_adapter_type;
extern struct device_type i2c_client_type;
extern const struct device_type i2c_adapter_type;
extern const struct device_type i2c_client_type;
/* --- General options ------------------------------------------------ */
......@@ -931,7 +931,7 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap)
static inline u8 i2c_8bit_addr_from_msg(const struct i2c_msg *msg)
{
return (msg->addr << 1) | (msg->flags & I2C_M_RD ? 1 : 0);
return (msg->addr << 1) | (msg->flags & I2C_M_RD);
}
u8 *i2c_get_dma_safe_msg_buf(struct i2c_msg *msg, unsigned int threshold);
......
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