This cycle, I2C removes the currently unused CLASS_DDC support

(controllers set the flag, but there is no client to use it). Also,
 CLASS_SPD support gets simplified to prepare removal in the future.
 Class based instantiation is not recommended these days anyhow.
 Furthermore, I2C core now creates a debugfs directory per I2C adapter.
 Current bus driver users were converted to use it. Then, there are also
 quite some driver updates. Standing out are patches for the wmt-driver
 which is refactored to support more variants. This is the rebased pull
 request where a large series for the designware driver was dropped.
 -----BEGIN PGP SIGNATURE-----
 
 iQJDBAABCgAtFiEEOZGx6rniZ1Gk92RdFA3kzBSgKbYFAmWph0UPHHdzYUBrZXJu
 ZWwub3JnAAoJEBQN5MwUoCm2kbIQAJotSmX0mM+nNPReYCMMiloxoxUwgpiErNwY
 WDrYQSezthAJ1LDsGOEeLcE4f4I+UcUHBO1BoERtOZg3cGtE0Ii5N845sp100S9O
 ktyaKS5utoErymThWFFrnZX60/8yKXUMzZmNzy96560gPcxbFyyyVhKfBSPzK9T+
 O8CGu7GRNqgWHlvH3yqGeCbreWYrYVSrluEpBu6807cp3zDxrU+autOnsewm5+md
 ka3DdqrbxJSblYK8fJKESAUgkRmZgYKbgl0iiCuqX+ib6I4OA3Z68ny7dl0fY3Ws
 vwt7d88SaBKDdJmUZyb/sm4aJsW69GN+ECZolxrn4TIw45k4tes2s6Ma5+TV3E9h
 Fd1RuqduFEqQ7cj31UPe2x8rgj5Fo5nbjCWxdZv+/3zF8+cHwi8iwkp2PScsPCsa
 fmCdehUE5DrgobsRNANe6XJzxY5wp2VNpGEWKeaQz2Z0/d9T1YFS7a8aewvhXoPC
 isZboi6GQh2XoE8UgGJa29VUuaIkUW513DwCGw8mz1yKN+kHGcsRXXjkjaZoQn3U
 MMvh/zkI2Hpy/m2R8PWeIq5XhLJvmlZ19JJzUHJIjXh9Fn9EVtXhlUleh6mzMfeM
 n8NOg7Eukep2sBgmaufkUKz2Jtogs59YDSXZEvqJjIkPM2Wi0hA18Qj+pilES1ff
 3ckk3mxY
 =8D3Q
 -----END PGP SIGNATURE-----

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

Pull i2c updates from Wolfram Sang:
 "This removes the currently unused CLASS_DDC support (controllers set
  the flag, but there is no client to use it).

  Also, CLASS_SPD support gets simplified to prepare removal in the
  future. Class based instantiation is not recommended these days
  anyhow.

  Furthermore, I2C core now creates a debugfs directory per I2C adapter.
  Current bus driver users were converted to use it.

  Finally, quite some driver updates. Standing out are patches for the
  wmt-driver which is refactored to support more variants.

  This is the rebased pull request where a large series for the
  designware driver was dropped"

* tag 'i2c-for-6.8-rc1-rebased' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (38 commits)
  MAINTAINERS: use proper email for my I2C work
  i2c: stm32f7: add support for stm32mp25 soc
  i2c: stm32f7: perform I2C_ISR read once at beginning of event isr
  dt-bindings: i2c: document st,stm32mp25-i2c compatible
  i2c: stm32f7: simplify status messages in case of errors
  i2c: stm32f7: perform most of irq job in threaded handler
  i2c: stm32f7: use dev_err_probe upon calls of devm_request_irq
  i2c: i801: Add lis3lv02d for Dell XPS 15 7590
  i2c: i801: Add lis3lv02d for Dell Precision 3540
  i2c: wmt: Reduce redundant: REG_CR setting
  i2c: wmt: Reduce redundant: function parameter
  i2c: wmt: Reduce redundant: clock mode setting
  i2c: wmt: Reduce redundant: wait event complete
  i2c: wmt: Reduce redundant: bus busy check
  i2c: mux: reg: Remove class-based device auto-detection support
  i2c: make i2c_bus_type const
  dt-bindings: at24: add ROHM BR24G04
  eeprom: at24: use of_match_ptr()
  i2c: cpm: Remove linux,i2c-index conversion from be32
  i2c: imx: Make SDA actually optional for bus recovering
  ...
This commit is contained in:
Linus Torvalds 2024-01-18 17:29:01 -08:00
commit ed8d84530a
78 changed files with 405 additions and 454 deletions

View File

@ -123,6 +123,7 @@ properties:
- enum:
- onnn,cat24c04
- onnn,cat24c05
- rohm,br24g04
- const: atmel,24c04
- items:
- const: renesas,r1ex24016

View File

@ -19,6 +19,7 @@ allOf:
- st,stm32f7-i2c
- st,stm32mp13-i2c
- st,stm32mp15-i2c
- st,stm32mp25-i2c
then:
properties:
i2c-scl-rising-time-ns:
@ -41,6 +42,30 @@ allOf:
clock-frequency:
enum: [100000, 400000]
- if:
properties:
compatible:
contains:
enum:
- st,stm32f4-i2c
- st,stm32f7-i2c
- st,stm32mp13-i2c
- st,stm32mp15-i2c
then:
properties:
interrupts:
minItems: 2
interrupt-names:
minItems: 2
else:
properties:
interrupts:
maxItems: 1
interrupt-names:
maxItems: 1
properties:
compatible:
enum:
@ -48,6 +73,7 @@ properties:
- st,stm32f7-i2c
- st,stm32mp13-i2c
- st,stm32mp15-i2c
- st,stm32mp25-i2c
reg:
maxItems: 1
@ -56,11 +82,13 @@ properties:
items:
- description: interrupt ID for I2C event
- description: interrupt ID for I2C error
minItems: 1
interrupt-names:
items:
- const: event
- const: error
minItems: 1
resets:
maxItems: 1

View File

@ -10061,7 +10061,7 @@ F: Documentation/i2c/busses/i2c-parport.rst
F: drivers/i2c/busses/i2c-parport.c
I2C SUBSYSTEM
M: Wolfram Sang <wsa@kernel.org>
M: Wolfram Sang <wsa+renesas@sang-engineering.com>
L: linux-i2c@vger.kernel.org
S: Maintained
W: https://i2c.wiki.kernel.org/

View File

@ -175,7 +175,6 @@ struct amdgpu_i2c_chan *amdgpu_i2c_create(struct drm_device *dev,
i2c->rec = *rec;
i2c->adapter.owner = THIS_MODULE;
i2c->adapter.class = I2C_CLASS_DDC;
i2c->adapter.dev.parent = dev->dev;
i2c->dev = dev;
i2c_set_adapdata(&i2c->adapter, i2c);

View File

@ -7615,7 +7615,6 @@ create_i2c(struct ddc_service *ddc_service,
if (!i2c)
return NULL;
i2c->base.owner = THIS_MODULE;
i2c->base.class = I2C_CLASS_DDC;
i2c->base.dev.parent = &adev->pdev->dev;
i2c->base.algo = &amdgpu_dm_i2c_algo;
snprintf(i2c->base.name, sizeof(i2c->base.name), "AMDGPU DM i2c hw bus %d", link_index);

View File

@ -1530,7 +1530,6 @@ static int aldebaran_i2c_control_init(struct smu_context *smu)
smu_i2c->port = 0;
mutex_init(&smu_i2c->mutex);
control->owner = THIS_MODULE;
control->class = I2C_CLASS_SPD;
control->dev.parent = &adev->pdev->dev;
control->algo = &aldebaran_i2c_algo;
snprintf(control->name, sizeof(control->name), "AMDGPU SMU 0");

View File

@ -2696,7 +2696,6 @@ static int smu_v13_0_0_i2c_control_init(struct smu_context *smu)
smu_i2c->port = i;
mutex_init(&smu_i2c->mutex);
control->owner = THIS_MODULE;
control->class = I2C_CLASS_SPD;
control->dev.parent = &adev->pdev->dev;
control->algo = &smu_v13_0_0_i2c_algo;
snprintf(control->name, sizeof(control->name), "AMDGPU SMU %d", i);

View File

@ -1936,7 +1936,6 @@ static int smu_v13_0_6_i2c_control_init(struct smu_context *smu)
smu_i2c->port = i;
mutex_init(&smu_i2c->mutex);
control->owner = THIS_MODULE;
control->class = I2C_CLASS_SPD;
control->dev.parent = &adev->pdev->dev;
control->algo = &smu_v13_0_6_i2c_algo;
snprintf(control->name, sizeof(control->name), "AMDGPU SMU %d", i);

View File

@ -120,7 +120,6 @@ struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev)
return NULL;
i2c->adapter.owner = THIS_MODULE;
i2c->adapter.class = I2C_CLASS_DDC;
i2c->adapter.dev.parent = dev->dev;
i2c->dev = dev;
i2c_set_adapdata(&i2c->adapter, i2c);

View File

@ -515,7 +515,6 @@ static struct i2c_adapter *dw_hdmi_i2c_adapter(struct dw_hdmi *hdmi)
init_completion(&i2c->cmp);
adap = &i2c->adap;
adap->class = I2C_CLASS_DDC;
adap->owner = THIS_MODULE;
adap->dev.parent = hdmi->dev;
adap->algo = &dw_hdmi_algorithm;

View File

@ -2102,7 +2102,6 @@ int drm_dp_aux_register(struct drm_dp_aux *aux)
if (!aux->ddc.algo)
drm_dp_aux_init(aux);
aux->ddc.class = I2C_CLASS_DDC;
aux->ddc.owner = THIS_MODULE;
aux->ddc.dev.parent = aux->dev;

View File

@ -5926,7 +5926,6 @@ static int drm_dp_mst_register_i2c_bus(struct drm_dp_mst_port *port)
aux->ddc.algo_data = aux;
aux->ddc.retries = 3;
aux->ddc.class = I2C_CLASS_DDC;
aux->ddc.owner = THIS_MODULE;
/* FIXME: set the kdev of the port's connector as parent */
aux->ddc.dev.parent = parent_dev;

View File

@ -855,7 +855,6 @@ cdv_intel_dp_i2c_init(struct gma_connector *connector,
memset(&intel_dp->adapter, '\0', sizeof (intel_dp->adapter));
intel_dp->adapter.owner = THIS_MODULE;
intel_dp->adapter.class = I2C_CLASS_DDC;
strncpy (intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1);
intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0';
intel_dp->adapter.algo_data = &intel_dp->algo;

View File

@ -411,7 +411,6 @@ int gma_intel_setup_gmbus(struct drm_device *dev)
struct intel_gmbus *bus = &dev_priv->gmbus[i];
bus->adapter.owner = THIS_MODULE;
bus->adapter.class = I2C_CLASS_DDC;
snprintf(bus->adapter.name,
sizeof(bus->adapter.name),
"gma500 gmbus %s",

View File

@ -168,7 +168,6 @@ static struct i2c_adapter oaktrail_hdmi_i2c_adapter = {
.name = "oaktrail_hdmi_i2c",
.nr = 3,
.owner = THIS_MODULE,
.class = I2C_CLASS_DDC,
.algo = &oaktrail_hdmi_i2c_algorithm,
};

View File

@ -2426,7 +2426,6 @@ psb_intel_sdvo_init_ddc_proxy(struct psb_intel_sdvo *sdvo,
struct drm_device *dev)
{
sdvo->ddc.owner = THIS_MODULE;
sdvo->ddc.class = I2C_CLASS_DDC;
snprintf(sdvo->ddc.name, I2C_NAME_SIZE, "SDVO DDC proxy");
sdvo->ddc.dev.parent = dev->dev;
sdvo->ddc.algo_data = sdvo;

View File

@ -81,7 +81,6 @@ int hibmc_ddc_create(struct drm_device *drm_dev,
struct hibmc_connector *connector)
{
connector->adapter.owner = THIS_MODULE;
connector->adapter.class = I2C_CLASS_DDC;
snprintf(connector->adapter.name, I2C_NAME_SIZE, "HIS i2c bit bus");
connector->adapter.dev.parent = drm_dev->dev;
i2c_set_adapdata(&connector->adapter, connector);

View File

@ -899,7 +899,6 @@ int intel_gmbus_setup(struct drm_i915_private *i915)
}
bus->adapter.owner = THIS_MODULE;
bus->adapter.class = I2C_CLASS_DDC;
snprintf(bus->adapter.name,
sizeof(bus->adapter.name),
"i915 gmbus %s", gmbus_pin->name);

View File

@ -3327,7 +3327,6 @@ intel_sdvo_init_ddc_proxy(struct intel_sdvo_ddc *ddc,
ddc->ddc_bus = ddc_bus;
ddc->ddc.owner = THIS_MODULE;
ddc->ddc.class = I2C_CLASS_DDC;
snprintf(ddc->ddc.name, I2C_NAME_SIZE, "SDVO %c DDC%d",
port_name(sdvo->base.port), ddc_bus);
ddc->ddc.dev.parent = &pdev->dev;

View File

@ -154,7 +154,6 @@ int lsdc_create_i2c_chan(struct drm_device *ddev,
adapter = &li2c->adapter;
adapter->algo_data = &li2c->bit;
adapter->owner = THIS_MODULE;
adapter->class = I2C_CLASS_DDC;
adapter->dev.parent = ddev->dev;
adapter->nr = -1;

View File

@ -297,7 +297,6 @@ static int mtk_hdmi_ddc_probe(struct platform_device *pdev)
strscpy(ddc->adap.name, "mediatek-hdmi-ddc", sizeof(ddc->adap.name));
ddc->adap.owner = THIS_MODULE;
ddc->adap.class = I2C_CLASS_DDC;
ddc->adap.algo = &mtk_hdmi_ddc_algorithm;
ddc->adap.retries = 3;
ddc->adap.dev.of_node = dev->of_node;

View File

@ -106,7 +106,6 @@ int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c)
i2c->data = BIT(info->i2c.data_bit);
i2c->clock = BIT(info->i2c.clock_bit);
i2c->adapter.owner = THIS_MODULE;
i2c->adapter.class = I2C_CLASS_DDC;
i2c->adapter.dev.parent = dev->dev;
i2c->dev = dev;
i2c_set_adapdata(&i2c->adapter, i2c);

View File

@ -249,7 +249,6 @@ struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi)
i2c->owner = THIS_MODULE;
i2c->class = I2C_CLASS_DDC;
snprintf(i2c->name, sizeof(i2c->name), "msm hdmi i2c");
i2c->dev.parent = &hdmi->pdev->dev;
i2c->algo = &msm_hdmi_i2c_algorithm;

View File

@ -918,7 +918,6 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
i2c->rec = *rec;
i2c->adapter.owner = THIS_MODULE;
i2c->adapter.class = I2C_CLASS_DDC;
i2c->adapter.dev.parent = dev->dev;
i2c->dev = dev;
i2c_set_adapdata(&i2c->adapter, i2c);

View File

@ -792,7 +792,6 @@ static struct i2c_adapter *inno_hdmi_i2c_adapter(struct inno_hdmi *hdmi)
init_completion(&i2c->cmp);
adap = &i2c->adap;
adap->class = I2C_CLASS_DDC;
adap->owner = THIS_MODULE;
adap->dev.parent = hdmi->dev;
adap->dev.of_node = hdmi->dev->of_node;

View File

@ -715,7 +715,6 @@ static struct i2c_adapter *rk3066_hdmi_i2c_adapter(struct rk3066_hdmi *hdmi)
init_completion(&i2c->cmpltn);
adap = &i2c->adap;
adap->class = I2C_CLASS_DDC;
adap->owner = THIS_MODULE;
adap->dev.parent = hdmi->dev;
adap->dev.of_node = hdmi->dev->of_node;

View File

@ -302,7 +302,6 @@ int sun4i_hdmi_i2c_create(struct device *dev, struct sun4i_hdmi *hdmi)
return -ENOMEM;
adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_DDC;
adap->algo = &sun4i_hdmi_i2c_algorithm;
strscpy(adap->name, "sun4i_hdmi_i2c adapter", sizeof(adap->name));
i2c_set_adapdata(adap, hdmi);

View File

@ -477,7 +477,7 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter ali1535_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
};

View File

@ -390,7 +390,7 @@ static const struct i2c_algorithm ali1563_algorithm = {
static struct i2c_adapter ali1563_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.algo = &ali1563_algorithm,
};

View File

@ -461,7 +461,7 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter ali15x3_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
};

View File

@ -285,7 +285,7 @@ static const struct i2c_algorithm smbus_algorithm = {
struct i2c_adapter amd756_smbus = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
};

View File

@ -449,7 +449,7 @@ static int amd8111_probe(struct pci_dev *dev, const struct pci_device_id *id)
smbus->adapter.owner = THIS_MODULE;
snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
"SMBus2 AMD8111 adapter at %04x", smbus->base);
smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
smbus->adapter.class = I2C_CLASS_HWMON;
smbus->adapter.algo = &smbus_algorithm;
smbus->adapter.algo_data = smbus;

View File

@ -658,7 +658,7 @@ static int cpm_i2c_probe(struct platform_device *ofdev)
/* register new adapter to i2c module... */
data = of_get_property(ofdev->dev.of_node, "linux,i2c-index", &len);
cpm->adap.nr = (data && len == 4) ? be32_to_cpup(data) : -1;
cpm->adap.nr = (data && len == 4) ? *data : -1;
result = i2c_add_numbered_adapter(&cpm->adap);
if (result < 0)

View File

@ -188,7 +188,7 @@ static struct i2c_algo_pcf_data pcf_isa_data = {
static struct i2c_adapter pcf_isa_ops = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.algo_data = &pcf_isa_data,
.name = "i2c-elektor",
};

View File

@ -25,7 +25,6 @@ struct i2c_gpio_private_data {
struct i2c_algo_bit_data bit_data;
struct i2c_gpio_platform_data pdata;
#ifdef CONFIG_I2C_GPIO_FAULT_INJECTOR
struct dentry *debug_dir;
/* these must be protected by bus lock */
struct completion scl_irq_completion;
u64 scl_irq_data;
@ -72,7 +71,6 @@ static int i2c_gpio_getscl(void *data)
}
#ifdef CONFIG_I2C_GPIO_FAULT_INJECTOR
static struct dentry *i2c_gpio_debug_dir;
#define setsda(bd, val) ((bd)->setsda((bd)->data, val))
#define setscl(bd, val) ((bd)->setscl((bd)->data, val))
@ -258,41 +256,23 @@ static void i2c_gpio_fault_injector_init(struct platform_device *pdev)
{
struct i2c_gpio_private_data *priv = platform_get_drvdata(pdev);
/*
* If there will be a debugfs-dir per i2c adapter somewhen, put the
* 'fault-injector' dir there. Until then, we have a global dir with
* all adapters as subdirs.
*/
if (!i2c_gpio_debug_dir)
i2c_gpio_debug_dir = debugfs_create_dir("i2c-fault-injector", NULL);
priv->debug_dir = debugfs_create_dir(pdev->name, i2c_gpio_debug_dir);
init_completion(&priv->scl_irq_completion);
debugfs_create_file_unsafe("incomplete_address_phase", 0200, priv->debug_dir,
debugfs_create_file_unsafe("incomplete_address_phase", 0200, priv->adap.debugfs,
priv, &fops_incomplete_addr_phase);
debugfs_create_file_unsafe("incomplete_write_byte", 0200, priv->debug_dir,
debugfs_create_file_unsafe("incomplete_write_byte", 0200, priv->adap.debugfs,
priv, &fops_incomplete_write_byte);
if (priv->bit_data.getscl) {
debugfs_create_file_unsafe("inject_panic", 0200, priv->debug_dir,
debugfs_create_file_unsafe("inject_panic", 0200, priv->adap.debugfs,
priv, &fops_inject_panic);
debugfs_create_file_unsafe("lose_arbitration", 0200, priv->debug_dir,
debugfs_create_file_unsafe("lose_arbitration", 0200, priv->adap.debugfs,
priv, &fops_lose_arbitration);
}
debugfs_create_file_unsafe("scl", 0600, priv->debug_dir, priv, &fops_scl);
debugfs_create_file_unsafe("sda", 0600, priv->debug_dir, priv, &fops_sda);
}
static void i2c_gpio_fault_injector_exit(struct platform_device *pdev)
{
struct i2c_gpio_private_data *priv = platform_get_drvdata(pdev);
debugfs_remove_recursive(priv->debug_dir);
debugfs_create_file_unsafe("scl", 0600, priv->adap.debugfs, priv, &fops_scl);
debugfs_create_file_unsafe("sda", 0600, priv->adap.debugfs, priv, &fops_sda);
}
#else
static inline void i2c_gpio_fault_injector_init(struct platform_device *pdev) {}
static inline void i2c_gpio_fault_injector_exit(struct platform_device *pdev) {}
#endif /* CONFIG_I2C_GPIO_FAULT_INJECTOR*/
/* Get i2c-gpio properties from DT or ACPI table */
@ -444,7 +424,7 @@ static int i2c_gpio_probe(struct platform_device *pdev)
snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id);
adap->algo_data = bit_data;
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adap->class = I2C_CLASS_HWMON;
adap->dev.parent = dev;
device_set_node(&adap->dev, fwnode);
@ -475,8 +455,6 @@ static void i2c_gpio_remove(struct platform_device *pdev)
struct i2c_gpio_private_data *priv;
struct i2c_adapter *adap;
i2c_gpio_fault_injector_exit(pdev);
priv = platform_get_drvdata(pdev);
adap = &priv->adap;

View File

@ -1230,8 +1230,10 @@ static const struct {
* Additional individual entries were added after verification.
*/
{ "Latitude 5480", 0x29 },
{ "Precision 3540", 0x29 },
{ "Vostro V131", 0x1d },
{ "Vostro 5568", 0x29 },
{ "XPS 15 7590", 0x29 },
};
static void register_dell_lis3lv02d_i2c_device(struct i801_priv *priv)

View File

@ -739,7 +739,7 @@ static int iic_probe(struct platform_device *ofdev)
adap->dev.of_node = of_node_get(np);
strscpy(adap->name, "IBM IIC", sizeof(adap->name));
i2c_set_adapdata(adap, dev);
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adap->class = I2C_CLASS_HWMON;
adap->algo = &iic_algo;
adap->timeout = HZ;

View File

@ -1401,7 +1401,7 @@ static int i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
PINCTRL_STATE_DEFAULT);
i2c_imx->pinctrl_pins_gpio = pinctrl_lookup_state(i2c_imx->pinctrl,
"gpio");
rinfo->sda_gpiod = devm_gpiod_get(&pdev->dev, "sda", GPIOD_IN);
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 ||

View File

@ -478,7 +478,7 @@ iop3xx_i2c_probe(struct platform_device *pdev)
memcpy(new_adapter->name, pdev->name, strlen(pdev->name));
new_adapter->owner = THIS_MODULE;
new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
new_adapter->class = I2C_CLASS_HWMON;
new_adapter->dev.parent = &pdev->dev;
new_adapter->dev.of_node = pdev->dev.of_node;
new_adapter->nr = pdev->id;

View File

@ -249,7 +249,7 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter sch_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
};

View File

@ -283,8 +283,7 @@ static const struct i2c_algorithm kempld_i2c_algorithm = {
static const struct i2c_adapter kempld_i2c_adapter = {
.owner = THIS_MODULE,
.name = "i2c-kempld",
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD |
I2C_CLASS_DEPRECATED,
.class = I2C_CLASS_HWMON | I2C_CLASS_DEPRECATED,
.algo = &kempld_i2c_algorithm,
};

View File

@ -477,7 +477,7 @@ static const struct i2c_adapter_quirks mlxcpld_i2c_quirks_ext2 = {
static struct i2c_adapter mlxcpld_i2c_adapter = {
.owner = THIS_MODULE,
.name = "i2c-mlxcpld",
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.algo = &mlxcpld_i2c_algo,
.quirks = &mlxcpld_i2c_quirks,
.retries = MLXCPLD_I2C_RETR_NUM,

View File

@ -349,7 +349,7 @@ static int nforce2_probe_smb(struct pci_dev *dev, int bar, int alt_reg,
return -EBUSY;
}
smbus->adapter.owner = THIS_MODULE;
smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
smbus->adapter.class = I2C_CLASS_HWMON;
smbus->adapter.algo = &smbus_algorithm;
smbus->adapter.algo_data = smbus;
smbus->adapter.dev.parent = &dev->dev;

View File

@ -326,7 +326,6 @@ struct npcm_i2c {
u8 slv_rd_buf[MAX_I2C_HW_FIFO_SIZE];
u8 slv_wr_buf[MAX_I2C_HW_FIFO_SIZE];
#endif
struct dentry *debugfs; /* debugfs device directory */
u64 ber_cnt;
u64 rec_succ_cnt;
u64 rec_fail_cnt;
@ -2250,27 +2249,15 @@ static const struct i2c_algorithm npcm_i2c_algo = {
#endif
};
/* i2c debugfs directory: used to keep health monitor of i2c devices */
static struct dentry *npcm_i2c_debugfs_dir;
static void npcm_i2c_init_debugfs(struct platform_device *pdev,
struct npcm_i2c *bus)
{
struct dentry *d;
if (!npcm_i2c_debugfs_dir)
return;
d = debugfs_create_dir(dev_name(&pdev->dev), npcm_i2c_debugfs_dir);
if (IS_ERR_OR_NULL(d))
return;
debugfs_create_u64("ber_cnt", 0444, d, &bus->ber_cnt);
debugfs_create_u64("nack_cnt", 0444, d, &bus->nack_cnt);
debugfs_create_u64("rec_succ_cnt", 0444, d, &bus->rec_succ_cnt);
debugfs_create_u64("rec_fail_cnt", 0444, d, &bus->rec_fail_cnt);
debugfs_create_u64("timeout_cnt", 0444, d, &bus->timeout_cnt);
debugfs_create_u64("tx_complete_cnt", 0444, d, &bus->tx_complete_cnt);
bus->debugfs = d;
debugfs_create_u64("ber_cnt", 0444, bus->adap.debugfs, &bus->ber_cnt);
debugfs_create_u64("nack_cnt", 0444, bus->adap.debugfs, &bus->nack_cnt);
debugfs_create_u64("rec_succ_cnt", 0444, bus->adap.debugfs, &bus->rec_succ_cnt);
debugfs_create_u64("rec_fail_cnt", 0444, bus->adap.debugfs, &bus->rec_fail_cnt);
debugfs_create_u64("timeout_cnt", 0444, bus->adap.debugfs, &bus->timeout_cnt);
debugfs_create_u64("tx_complete_cnt", 0444, bus->adap.debugfs, &bus->tx_complete_cnt);
}
static int npcm_i2c_probe_bus(struct platform_device *pdev)
@ -2362,7 +2349,6 @@ static void npcm_i2c_remove_bus(struct platform_device *pdev)
unsigned long lock_flags;
struct npcm_i2c *bus = platform_get_drvdata(pdev);
debugfs_remove_recursive(bus->debugfs);
spin_lock_irqsave(&bus->lock, lock_flags);
npcm_i2c_disable(bus);
spin_unlock_irqrestore(&bus->lock, lock_flags);
@ -2385,28 +2371,7 @@ static struct platform_driver npcm_i2c_bus_driver = {
}
};
static int __init npcm_i2c_init(void)
{
int ret;
npcm_i2c_debugfs_dir = debugfs_create_dir("npcm_i2c", NULL);
ret = platform_driver_register(&npcm_i2c_bus_driver);
if (ret) {
debugfs_remove_recursive(npcm_i2c_debugfs_dir);
return ret;
}
return 0;
}
module_init(npcm_i2c_init);
static void __exit npcm_i2c_exit(void)
{
platform_driver_unregister(&npcm_i2c_bus_driver);
debugfs_remove_recursive(npcm_i2c_debugfs_dir);
}
module_exit(npcm_i2c_exit);
module_platform_driver(npcm_i2c_bus_driver);
MODULE_AUTHOR("Avi Fishman <avi.fishman@gmail.com>");
MODULE_AUTHOR("Tali Perry <tali.perry@nuvoton.com>");

View File

@ -56,7 +56,7 @@ static int pasemi_smb_pci_probe(struct pci_dev *dev,
if (!smbus->ioaddr)
return -EBUSY;
smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
smbus->adapter.class = I2C_CLASS_HWMON;
error = pasemi_i2c_common_probe(smbus);
if (error)
return error;

View File

@ -943,7 +943,7 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
}
adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adap->class = I2C_CLASS_HWMON;
adap->algo = sb800_main ? &piix4_smbus_algorithm_sb800
: &smbus_algorithm;

View File

@ -89,6 +89,7 @@
#define TMDMAE BIT(0) /* DMA Master Transmitted Enable */
/* ICCCR2 */
#define FMPE BIT(7) /* Fast Mode Plus Enable */
#define CDFD BIT(2) /* CDF Disable */
#define HLSE BIT(1) /* HIGH/LOW Separate Control Enable */
#define SME BIT(0) /* SCL Mask Enable */
@ -122,16 +123,18 @@
#define ID_NACK BIT(4)
#define ID_EPROTO BIT(5)
/* persistent flags */
#define ID_P_FMPLUS BIT(27)
#define ID_P_NOT_ATOMIC BIT(28)
#define ID_P_HOST_NOTIFY BIT(29)
#define ID_P_NO_RXDMA BIT(30) /* HW forbids RXDMA sometimes */
#define ID_P_PM_BLOCKED BIT(31)
#define ID_P_MASK GENMASK(31, 28)
#define ID_P_MASK GENMASK(31, 27)
enum rcar_i2c_type {
I2C_RCAR_GEN1,
I2C_RCAR_GEN2,
I2C_RCAR_GEN3,
I2C_RCAR_GEN4,
};
struct rcar_i2c_priv {
@ -148,6 +151,7 @@ struct rcar_i2c_priv {
u32 icccr;
u16 schd;
u16 scld;
u8 smd;
u8 recovery_icmcr; /* protected by adapter lock */
enum rcar_i2c_type devtype;
struct i2c_client *slave;
@ -239,9 +243,14 @@ static void rcar_i2c_init(struct rcar_i2c_priv *priv)
if (priv->devtype < I2C_RCAR_GEN3) {
rcar_i2c_write(priv, ICCCR, priv->icccr);
} else {
rcar_i2c_write(priv, ICCCR2, CDFD | HLSE | SME);
u32 icccr2 = CDFD | HLSE | SME;
if (priv->flags & ID_P_FMPLUS)
icccr2 |= FMPE;
rcar_i2c_write(priv, ICCCR2, icccr2);
rcar_i2c_write(priv, ICCCR, priv->icccr);
rcar_i2c_write(priv, ICMPR, RCAR_DEFAULT_SMD);
rcar_i2c_write(priv, ICMPR, priv->smd);
rcar_i2c_write(priv, ICHPR, priv->schd);
rcar_i2c_write(priv, ICLPR, priv->scld);
rcar_i2c_write(priv, ICFBSCR, TCYC17);
@ -278,6 +287,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv)
/* Fall back to previously used values if not supplied */
i2c_parse_fw_timings(dev, &t, false);
priv->smd = RCAR_DEFAULT_SMD;
/*
* calculate SCL clock
@ -303,6 +313,11 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv)
if (cdf >= 1U << cdf_width)
goto err_no_val;
if (t.bus_freq_hz > I2C_MAX_FAST_MODE_FREQ && priv->devtype >= I2C_RCAR_GEN4)
priv->flags |= ID_P_FMPLUS;
else
priv->flags &= ~ID_P_FMPLUS;
/* On Gen3+, we use cdf only for the filters, not as a SCL divider */
ick = rate / (priv->devtype < I2C_RCAR_GEN3 ? (cdf + 1) : 1);
@ -344,30 +359,30 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv)
* x as a base value for the SCLD/SCHD ratio:
*
* SCL = clkp / (8 + 2 * SMD + SCLD + SCHD + F[(ticf + tr + intd) * clkp])
* SCL = clkp / (8 + 2 * RCAR_DEFAULT_SMD + RCAR_SCLD_RATIO * x
* SCL = clkp / (8 + 2 * SMD + RCAR_SCLD_RATIO * x
* + RCAR_SCHD_RATIO * x + F[...])
*
* with: sum_ratio = RCAR_SCLD_RATIO + RCAR_SCHD_RATIO
* and: smd = RCAR_DEFAULT_SMD
*
* SCL = clkp / (8 + 2 * smd + sum_ratio * x + F[...])
* 8 + 2 * smd + sum_ratio * x + F[...] = clkp / SCL
* x = ((clkp / SCL) - 8 - 2 * smd - F[...]) / sum_ratio
*/
x = DIV_ROUND_UP(rate, t.bus_freq_hz ?: 1);
x = DIV_ROUND_UP(x - 8 - 2 * RCAR_DEFAULT_SMD - round, sum_ratio);
scl = rate / (8 + 2 * RCAR_DEFAULT_SMD + sum_ratio * x + round);
x = DIV_ROUND_UP(x - 8 - 2 * priv->smd - round, sum_ratio);
scl = rate / (8 + 2 * priv->smd + sum_ratio * x + round);
/* Bail out if values don't fit into 16 bit or SMD became too large */
if (x * RCAR_SCLD_RATIO > 0xffff || RCAR_DEFAULT_SMD > x * RCAR_SCHD_RATIO)
if (x == 0 || x * RCAR_SCLD_RATIO > 0xffff)
goto err_no_val;
priv->icccr = cdf;
priv->schd = RCAR_SCHD_RATIO * x;
priv->scld = RCAR_SCLD_RATIO * x;
if (priv->smd >= priv->schd)
priv->smd = priv->schd - 1;
dev_dbg(dev, "clk %u/%u(%lu), round %u, CDF: %u SCHD %u SCLD %u\n",
scl, t.bus_freq_hz, rate, round, cdf, priv->schd, priv->scld);
dev_dbg(dev, "clk %u/%u(%lu), round %u, CDF: %u SCHD %u SCLD %u SMD %u\n",
scl, t.bus_freq_hz, rate, round, cdf, priv->schd, priv->scld, priv->smd);
}
return 0;
@ -431,8 +446,8 @@ static void rcar_i2c_cleanup_dma(struct rcar_i2c_priv *priv, bool terminate)
dma_unmap_single(chan->device->dev, sg_dma_address(&priv->sg),
sg_dma_len(&priv->sg), priv->dma_direction);
/* Gen3 can only do one RXDMA per transfer and we just completed it */
if (priv->devtype == I2C_RCAR_GEN3 &&
/* Gen3+ can only do one RXDMA per transfer and we just completed it */
if (priv->devtype >= I2C_RCAR_GEN3 &&
priv->dma_direction == DMA_FROM_DEVICE)
priv->flags |= ID_P_NO_RXDMA;
@ -886,8 +901,8 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
if (ret < 0)
goto out;
/* Gen3 needs a reset before allowing RXDMA once */
if (priv->devtype == I2C_RCAR_GEN3) {
/* Gen3+ needs a reset. That also allows RXDMA once */
if (priv->devtype >= I2C_RCAR_GEN3) {
priv->flags &= ~ID_P_NO_RXDMA;
ret = rcar_i2c_do_reset(priv);
if (ret)
@ -1072,10 +1087,12 @@ static const struct of_device_id rcar_i2c_dt_ids[] = {
{ .compatible = "renesas,i2c-r8a7794", .data = (void *)I2C_RCAR_GEN2 },
{ .compatible = "renesas,i2c-r8a7795", .data = (void *)I2C_RCAR_GEN3 },
{ .compatible = "renesas,i2c-r8a7796", .data = (void *)I2C_RCAR_GEN3 },
/* S4 has no FM+ bit */
{ .compatible = "renesas,i2c-r8a779f0", .data = (void *)I2C_RCAR_GEN3 },
{ .compatible = "renesas,rcar-gen1-i2c", .data = (void *)I2C_RCAR_GEN1 },
{ .compatible = "renesas,rcar-gen2-i2c", .data = (void *)I2C_RCAR_GEN2 },
{ .compatible = "renesas,rcar-gen3-i2c", .data = (void *)I2C_RCAR_GEN3 },
{ .compatible = "renesas,rcar-gen4-i2c", .data = (void *)I2C_RCAR_GEN3 },
{ .compatible = "renesas,rcar-gen4-i2c", .data = (void *)I2C_RCAR_GEN4 },
{},
};
MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids);
@ -1151,7 +1168,7 @@ static int rcar_i2c_probe(struct platform_device *pdev)
if (of_property_read_bool(dev->of_node, "smbus"))
priv->flags |= ID_P_HOST_NOTIFY;
if (priv->devtype == I2C_RCAR_GEN3) {
if (priv->devtype >= I2C_RCAR_GEN3) {
priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(priv->rstc)) {
ret = PTR_ERR(priv->rstc);

View File

@ -1295,8 +1295,12 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
return -EINVAL;
}
/* 27+i: write mask, 11+i: value */
value = BIT(27 + bus_nr) | BIT(11 + bus_nr);
/* rv1126 i2c2 uses non-sequential write mask 20, value 4 */
if (i2c->soc_data == &rv1126_soc_data && bus_nr == 2)
value = BIT(20) | BIT(4);
else
/* 27+i: write mask, 11+i: value */
value = BIT(27 + bus_nr) | BIT(11 + bus_nr);
ret = regmap_write(grf, i2c->soc_data->grf_offset, value);
if (ret != 0) {

View File

@ -76,6 +76,7 @@
#define QUIRK_HDMIPHY (1 << 1)
#define QUIRK_NO_GPIO (1 << 2)
#define QUIRK_POLL (1 << 3)
#define QUIRK_ATOMIC (1 << 4)
/* Max time to wait for bus to become idle after a xfer (in us) */
#define S3C2410_IDLE_TIMEOUT 5000
@ -174,7 +175,7 @@ static inline void s3c24xx_i2c_master_complete(struct s3c24xx_i2c *i2c, int ret)
if (ret)
i2c->msg_idx = ret;
if (!(i2c->quirks & QUIRK_POLL))
if (!(i2c->quirks & (QUIRK_POLL | QUIRK_ATOMIC)))
wake_up(&i2c->wait);
}
@ -216,8 +217,17 @@ static bool is_ack(struct s3c24xx_i2c *i2c)
int tries;
for (tries = 50; tries; --tries) {
if (readl(i2c->regs + S3C2410_IICCON)
& S3C2410_IICCON_IRQPEND) {
unsigned long tmp = readl(i2c->regs + S3C2410_IICCON);
if (!(tmp & S3C2410_IICCON_ACKEN)) {
/*
* Wait a bit for the bus to stabilize,
* delay estimated experimentally.
*/
usleep_range(100, 200);
return true;
}
if (tmp & S3C2410_IICCON_IRQPEND) {
if (!(readl(i2c->regs + S3C2410_IICSTAT)
& S3C2410_IICSTAT_LASTBIT))
return true;
@ -270,16 +280,6 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
stat |= S3C2410_IICSTAT_START;
writel(stat, i2c->regs + S3C2410_IICSTAT);
if (i2c->quirks & QUIRK_POLL) {
while ((i2c->msg_num != 0) && is_ack(i2c)) {
i2c_s3c_irq_nextbyte(i2c, stat);
stat = readl(i2c->regs + S3C2410_IICSTAT);
if (stat & S3C2410_IICSTAT_ARBITR)
dev_err(i2c->dev, "deal with arbitration loss\n");
}
}
}
static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)
@ -685,7 +685,7 @@ static void s3c24xx_i2c_wait_idle(struct s3c24xx_i2c *i2c)
static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
struct i2c_msg *msgs, int num)
{
unsigned long timeout;
unsigned long timeout = 0;
int ret;
ret = s3c24xx_i2c_set_master(i2c);
@ -704,17 +704,20 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
s3c24xx_i2c_enable_irq(i2c);
s3c24xx_i2c_message_start(i2c, msgs);
if (i2c->quirks & QUIRK_POLL) {
ret = i2c->msg_idx;
if (i2c->quirks & (QUIRK_POLL | QUIRK_ATOMIC)) {
while ((i2c->msg_num != 0) && is_ack(i2c)) {
unsigned long stat = readl(i2c->regs + S3C2410_IICSTAT);
if (ret != num)
dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
i2c_s3c_irq_nextbyte(i2c, stat);
goto out;
stat = readl(i2c->regs + S3C2410_IICSTAT);
if (stat & S3C2410_IICSTAT_ARBITR)
dev_err(i2c->dev, "deal with arbitration loss\n");
}
} else {
timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
}
timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
ret = i2c->msg_idx;
/*
@ -773,6 +776,21 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
return -EREMOTEIO;
}
static int s3c24xx_i2c_xfer_atomic(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num)
{
struct s3c24xx_i2c *i2c = (struct s3c24xx_i2c *)adap->algo_data;
int ret;
disable_irq(i2c->irq);
i2c->quirks |= QUIRK_ATOMIC;
ret = s3c24xx_i2c_xfer(adap, msgs, num);
i2c->quirks &= ~QUIRK_ATOMIC;
enable_irq(i2c->irq);
return ret;
}
/* declare our i2c functionality */
static u32 s3c24xx_i2c_func(struct i2c_adapter *adap)
{
@ -783,6 +801,7 @@ static u32 s3c24xx_i2c_func(struct i2c_adapter *adap)
/* i2c bus registration info */
static const struct i2c_algorithm s3c24xx_i2c_algorithm = {
.master_xfer = s3c24xx_i2c_xfer,
.master_xfer_atomic = s3c24xx_i2c_xfer_atomic,
.functionality = s3c24xx_i2c_func,
};

View File

@ -385,7 +385,7 @@ static int smbus_cmi_probe(struct platform_device *device)
smbus_cmi->adapter.owner = THIS_MODULE;
smbus_cmi->adapter.algo = &acpi_smbus_cmi_algorithm;
smbus_cmi->adapter.algo_data = smbus_cmi;
smbus_cmi->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
smbus_cmi->adapter.class = I2C_CLASS_HWMON;
smbus_cmi->adapter.dev.parent = &device->dev;
ret = i2c_add_adapter(&smbus_cmi->adapter);

View File

@ -477,7 +477,7 @@ static int sh7760_i2c_probe(struct platform_device *pdev)
id->adap.nr = pdev->id;
id->adap.algo = &sh7760_i2c_algo;
id->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
id->adap.class = I2C_CLASS_HWMON;
id->adap.retries = 3;
id->adap.algo_data = id;
id->adap.dev.parent = &pdev->dev;

View File

@ -142,7 +142,7 @@ static struct i2c_algo_sibyte_data sibyte_board_data[2] = {
static struct i2c_adapter sibyte_board_adapter[2] = {
{
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.algo = NULL,
.algo_data = &sibyte_board_data[0],
.nr = 0,
@ -150,7 +150,7 @@ static struct i2c_adapter sibyte_board_adapter[2] = {
},
{
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.algo = NULL,
.algo_data = &sibyte_board_data[1],
.nr = 1,

View File

@ -353,7 +353,7 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter sis5595_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
};

View File

@ -493,7 +493,7 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter sis630_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
.retries = 3
};

View File

@ -228,7 +228,7 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter sis96x_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
};

View File

@ -50,6 +50,7 @@
#define STM32F7_I2C_TXDR 0x28
/* STM32F7 I2C control 1 */
#define STM32_I2C_CR1_FMP BIT(24)
#define STM32F7_I2C_CR1_PECEN BIT(23)
#define STM32F7_I2C_CR1_ALERTEN BIT(22)
#define STM32F7_I2C_CR1_SMBHEN BIT(20)
@ -226,6 +227,8 @@ struct stm32f7_i2c_spec {
* @rise_time: Rise time (ns)
* @fall_time: Fall time (ns)
* @fmp_clr_offset: Fast Mode Plus clear register offset from set register
* @single_it_line: Only a single IT line is used for both events/errors
* @fmp_cr1_bit: Fast Mode Plus control is done via a bit in CR1
*/
struct stm32f7_i2c_setup {
u32 speed_freq;
@ -233,6 +236,8 @@ struct stm32f7_i2c_setup {
u32 rise_time;
u32 fall_time;
u32 fmp_clr_offset;
bool single_it_line;
bool fmp_cr1_bit;
};
/**
@ -418,6 +423,13 @@ static const struct stm32f7_i2c_setup stm32mp13_setup = {
.fmp_clr_offset = 0x4,
};
static const struct stm32f7_i2c_setup stm32mp25_setup = {
.rise_time = STM32F7_I2C_RISE_TIME_DEFAULT,
.fall_time = STM32F7_I2C_FALL_TIME_DEFAULT,
.single_it_line = true,
.fmp_cr1_bit = true,
};
static inline void stm32f7_i2c_set_bits(void __iomem *reg, u32 mask)
{
writel_relaxed(readl_relaxed(reg) | mask, reg);
@ -1419,15 +1431,13 @@ static bool stm32f7_i2c_is_slave_busy(struct stm32f7_i2c_dev *i2c_dev)
return i == busy;
}
static irqreturn_t stm32f7_i2c_slave_isr_event(struct stm32f7_i2c_dev *i2c_dev)
static irqreturn_t stm32f7_i2c_slave_isr_event(struct stm32f7_i2c_dev *i2c_dev, u32 status)
{
void __iomem *base = i2c_dev->base;
u32 cr2, status, mask;
u32 cr2, mask;
u8 val;
int ret;
status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);
/* Slave transmitter mode */
if (status & STM32F7_I2C_ISR_TXIS) {
i2c_slave_event(i2c_dev->slave_running,
@ -1494,142 +1504,17 @@ static irqreturn_t stm32f7_i2c_slave_isr_event(struct stm32f7_i2c_dev *i2c_dev)
return IRQ_HANDLED;
}
static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
static irqreturn_t stm32f7_i2c_handle_isr_errs(struct stm32f7_i2c_dev *i2c_dev, u32 status)
{
struct stm32f7_i2c_dev *i2c_dev = data;
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
struct stm32_i2c_dma *dma = i2c_dev->dma;
void __iomem *base = i2c_dev->base;
u32 status, mask;
int ret = IRQ_HANDLED;
/* Check if the interrupt if for a slave device */
if (!i2c_dev->master_mode) {
ret = stm32f7_i2c_slave_isr_event(i2c_dev);
return ret;
}
status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);
/* Tx empty */
if (status & STM32F7_I2C_ISR_TXIS)
stm32f7_i2c_write_tx_data(i2c_dev);
/* RX not empty */
if (status & STM32F7_I2C_ISR_RXNE)
stm32f7_i2c_read_rx_data(i2c_dev);
/* NACK received */
if (status & STM32F7_I2C_ISR_NACKF) {
dev_dbg(i2c_dev->dev, "<%s>: Receive NACK (addr %x)\n",
__func__, f7_msg->addr);
writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR);
if (i2c_dev->use_dma) {
stm32f7_i2c_disable_dma_req(i2c_dev);
dmaengine_terminate_async(dma->chan_using);
}
f7_msg->result = -ENXIO;
}
/* STOP detection flag */
if (status & STM32F7_I2C_ISR_STOPF) {
/* Disable interrupts */
if (stm32f7_i2c_is_slave_registered(i2c_dev))
mask = STM32F7_I2C_XFER_IRQ_MASK;
else
mask = STM32F7_I2C_ALL_IRQ_MASK;
stm32f7_i2c_disable_irq(i2c_dev, mask);
/* Clear STOP flag */
writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR);
if (i2c_dev->use_dma && !f7_msg->result) {
ret = IRQ_WAKE_THREAD;
} else {
i2c_dev->master_mode = false;
complete(&i2c_dev->complete);
}
}
/* Transfer complete */
if (status & STM32F7_I2C_ISR_TC) {
if (f7_msg->stop) {
mask = STM32F7_I2C_CR2_STOP;
stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask);
} else if (i2c_dev->use_dma && !f7_msg->result) {
ret = IRQ_WAKE_THREAD;
} else if (f7_msg->smbus) {
stm32f7_i2c_smbus_rep_start(i2c_dev);
} else {
i2c_dev->msg_id++;
i2c_dev->msg++;
stm32f7_i2c_xfer_msg(i2c_dev, i2c_dev->msg);
}
}
if (status & STM32F7_I2C_ISR_TCR) {
if (f7_msg->smbus)
stm32f7_i2c_smbus_reload(i2c_dev);
else
stm32f7_i2c_reload(i2c_dev);
}
return ret;
}
static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data)
{
struct stm32f7_i2c_dev *i2c_dev = data;
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
struct stm32_i2c_dma *dma = i2c_dev->dma;
u32 status;
int ret;
/*
* Wait for dma transfer completion before sending next message or
* notity the end of xfer to the client
*/
ret = wait_for_completion_timeout(&i2c_dev->dma->dma_complete, HZ);
if (!ret) {
dev_dbg(i2c_dev->dev, "<%s>: Timed out\n", __func__);
stm32f7_i2c_disable_dma_req(i2c_dev);
dmaengine_terminate_async(dma->chan_using);
f7_msg->result = -ETIMEDOUT;
}
status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);
if (status & STM32F7_I2C_ISR_TC) {
if (f7_msg->smbus) {
stm32f7_i2c_smbus_rep_start(i2c_dev);
} else {
i2c_dev->msg_id++;
i2c_dev->msg++;
stm32f7_i2c_xfer_msg(i2c_dev, i2c_dev->msg);
}
} else {
i2c_dev->master_mode = false;
complete(&i2c_dev->complete);
}
return IRQ_HANDLED;
}
static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data)
{
struct stm32f7_i2c_dev *i2c_dev = data;
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
u16 addr = f7_msg->addr;
void __iomem *base = i2c_dev->base;
struct device *dev = i2c_dev->dev;
struct stm32_i2c_dma *dma = i2c_dev->dma;
u32 status;
status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);
/* Bus error */
if (status & STM32F7_I2C_ISR_BERR) {
dev_err(dev, "<%s>: Bus error accessing addr 0x%x\n",
__func__, f7_msg->addr);
dev_err(dev, "Bus error accessing addr 0x%x\n", addr);
writel_relaxed(STM32F7_I2C_ICR_BERRCF, base + STM32F7_I2C_ICR);
stm32f7_i2c_release_bus(&i2c_dev->adap);
f7_msg->result = -EIO;
@ -1637,21 +1522,19 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data)
/* Arbitration loss */
if (status & STM32F7_I2C_ISR_ARLO) {
dev_dbg(dev, "<%s>: Arbitration loss accessing addr 0x%x\n",
__func__, f7_msg->addr);
dev_dbg(dev, "Arbitration loss accessing addr 0x%x\n", addr);
writel_relaxed(STM32F7_I2C_ICR_ARLOCF, base + STM32F7_I2C_ICR);
f7_msg->result = -EAGAIN;
}
if (status & STM32F7_I2C_ISR_PECERR) {
dev_err(dev, "<%s>: PEC error in reception accessing addr 0x%x\n",
__func__, f7_msg->addr);
dev_err(dev, "PEC error in reception accessing addr 0x%x\n", addr);
writel_relaxed(STM32F7_I2C_ICR_PECCF, base + STM32F7_I2C_ICR);
f7_msg->result = -EINVAL;
}
if (status & STM32F7_I2C_ISR_ALERT) {
dev_dbg(dev, "<%s>: SMBus alert received\n", __func__);
dev_dbg(dev, "SMBus alert received\n");
writel_relaxed(STM32F7_I2C_ICR_ALERTCF, base + STM32F7_I2C_ICR);
i2c_handle_smbus_alert(i2c_dev->alert->ara);
return IRQ_HANDLED;
@ -1679,6 +1562,130 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data)
return IRQ_HANDLED;
}
#define STM32F7_ERR_EVENTS (STM32F7_I2C_ISR_BERR | STM32F7_I2C_ISR_ARLO |\
STM32F7_I2C_ISR_PECERR | STM32F7_I2C_ISR_ALERT)
static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
{
struct stm32f7_i2c_dev *i2c_dev = data;
u32 status;
status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);
/*
* Check if the interrupt is for a slave device or related
* to errors flags (in case of single it line mode)
*/
if (!i2c_dev->master_mode ||
(i2c_dev->setup.single_it_line && (status & STM32F7_ERR_EVENTS)))
return IRQ_WAKE_THREAD;
/* Tx empty */
if (status & STM32F7_I2C_ISR_TXIS)
stm32f7_i2c_write_tx_data(i2c_dev);
/* RX not empty */
if (status & STM32F7_I2C_ISR_RXNE)
stm32f7_i2c_read_rx_data(i2c_dev);
/* Wake up the thread if other flags are raised */
if (status &
(STM32F7_I2C_ISR_NACKF | STM32F7_I2C_ISR_STOPF |
STM32F7_I2C_ISR_TC | STM32F7_I2C_ISR_TCR))
return IRQ_WAKE_THREAD;
return IRQ_HANDLED;
}
static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data)
{
struct stm32f7_i2c_dev *i2c_dev = data;
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
struct stm32_i2c_dma *dma = i2c_dev->dma;
void __iomem *base = i2c_dev->base;
u32 status, mask;
int ret;
status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);
if (!i2c_dev->master_mode)
return stm32f7_i2c_slave_isr_event(i2c_dev, status);
/* Handle errors in case of this handler is used for events/errors */
if (i2c_dev->setup.single_it_line && (status & STM32F7_ERR_EVENTS))
return stm32f7_i2c_handle_isr_errs(i2c_dev, status);
/* NACK received */
if (status & STM32F7_I2C_ISR_NACKF) {
dev_dbg(i2c_dev->dev, "<%s>: Receive NACK (addr %x)\n",
__func__, f7_msg->addr);
writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR);
if (i2c_dev->use_dma) {
stm32f7_i2c_disable_dma_req(i2c_dev);
dmaengine_terminate_async(dma->chan_using);
}
f7_msg->result = -ENXIO;
}
if (status & STM32F7_I2C_ISR_TCR) {
if (f7_msg->smbus)
stm32f7_i2c_smbus_reload(i2c_dev);
else
stm32f7_i2c_reload(i2c_dev);
}
/* Transfer complete */
if (status & STM32F7_I2C_ISR_TC) {
/* Wait for dma transfer completion before sending next message */
if (i2c_dev->use_dma && !f7_msg->result) {
ret = wait_for_completion_timeout(&i2c_dev->dma->dma_complete, HZ);
if (!ret) {
dev_dbg(i2c_dev->dev, "<%s>: Timed out\n", __func__);
stm32f7_i2c_disable_dma_req(i2c_dev);
dmaengine_terminate_async(dma->chan_using);
f7_msg->result = -ETIMEDOUT;
}
}
if (f7_msg->stop) {
mask = STM32F7_I2C_CR2_STOP;
stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask);
} else if (f7_msg->smbus) {
stm32f7_i2c_smbus_rep_start(i2c_dev);
} else {
i2c_dev->msg_id++;
i2c_dev->msg++;
stm32f7_i2c_xfer_msg(i2c_dev, i2c_dev->msg);
}
}
/* STOP detection flag */
if (status & STM32F7_I2C_ISR_STOPF) {
/* Disable interrupts */
if (stm32f7_i2c_is_slave_registered(i2c_dev))
mask = STM32F7_I2C_XFER_IRQ_MASK;
else
mask = STM32F7_I2C_ALL_IRQ_MASK;
stm32f7_i2c_disable_irq(i2c_dev, mask);
/* Clear STOP flag */
writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR);
i2c_dev->master_mode = false;
complete(&i2c_dev->complete);
}
return IRQ_HANDLED;
}
static irqreturn_t stm32f7_i2c_isr_error_thread(int irq, void *data)
{
struct stm32f7_i2c_dev *i2c_dev = data;
u32 status;
status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);
return stm32f7_i2c_handle_isr_errs(i2c_dev, status);
}
static int stm32f7_i2c_wait_polling(struct stm32f7_i2c_dev *i2c_dev)
{
ktime_t timeout = ktime_add_ms(ktime_get(), i2c_dev->adap.timeout);
@ -2012,23 +2019,27 @@ static int stm32f7_i2c_unreg_slave(struct i2c_client *slave)
static int stm32f7_i2c_write_fm_plus_bits(struct stm32f7_i2c_dev *i2c_dev,
bool enable)
{
int ret;
int ret = 0;
if (i2c_dev->bus_rate <= I2C_MAX_FAST_MODE_FREQ ||
IS_ERR_OR_NULL(i2c_dev->regmap))
(!i2c_dev->setup.fmp_cr1_bit && IS_ERR_OR_NULL(i2c_dev->regmap)))
/* Optional */
return 0;
if (i2c_dev->fmp_sreg == i2c_dev->fmp_creg)
ret = regmap_update_bits(i2c_dev->regmap,
i2c_dev->fmp_sreg,
i2c_dev->fmp_mask,
enable ? i2c_dev->fmp_mask : 0);
else
ret = regmap_write(i2c_dev->regmap,
enable ? i2c_dev->fmp_sreg :
i2c_dev->fmp_creg,
i2c_dev->fmp_mask);
if (i2c_dev->setup.fmp_cr1_bit) {
if (enable)
stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1, STM32_I2C_CR1_FMP);
else
stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1, STM32_I2C_CR1_FMP);
} else {
if (i2c_dev->fmp_sreg == i2c_dev->fmp_creg)
ret = regmap_update_bits(i2c_dev->regmap, i2c_dev->fmp_sreg,
i2c_dev->fmp_mask, enable ? i2c_dev->fmp_mask : 0);
else
ret = regmap_write(i2c_dev->regmap,
enable ? i2c_dev->fmp_sreg : i2c_dev->fmp_creg,
i2c_dev->fmp_mask);
}
return ret;
}
@ -2162,6 +2173,13 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
if (!i2c_dev)
return -ENOMEM;
setup = of_device_get_match_data(&pdev->dev);
if (!setup) {
dev_err(&pdev->dev, "Can't get device data\n");
return -ENODEV;
}
i2c_dev->setup = *setup;
i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(i2c_dev->base))
return PTR_ERR(i2c_dev->base);
@ -2171,10 +2189,6 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
if (irq_event < 0)
return irq_event;
irq_error = platform_get_irq(pdev, 1);
if (irq_error < 0)
return irq_error;
i2c_dev->wakeup_src = of_property_read_bool(pdev->dev.of_node,
"wakeup-source");
@ -2199,26 +2213,22 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
stm32f7_i2c_isr_event_thread,
IRQF_ONESHOT,
pdev->name, i2c_dev);
if (ret) {
dev_err(&pdev->dev, "Failed to request irq event %i\n",
irq_event);
return ret;
}
if (ret)
return dev_err_probe(&pdev->dev, ret, "Failed to request irq event\n");
ret = devm_request_irq(&pdev->dev, irq_error, stm32f7_i2c_isr_error, 0,
pdev->name, i2c_dev);
if (ret) {
dev_err(&pdev->dev, "Failed to request irq error %i\n",
irq_error);
return ret;
}
if (!i2c_dev->setup.single_it_line) {
irq_error = platform_get_irq(pdev, 1);
if (irq_error < 0)
return irq_error;
setup = of_device_get_match_data(&pdev->dev);
if (!setup) {
dev_err(&pdev->dev, "Can't get device data\n");
return -ENODEV;
ret = devm_request_threaded_irq(&pdev->dev, irq_error,
NULL,
stm32f7_i2c_isr_error_thread,
IRQF_ONESHOT,
pdev->name, i2c_dev);
if (ret)
return dev_err_probe(&pdev->dev, ret, "Failed to request irq error\n");
}
i2c_dev->setup = *setup;
ret = stm32f7_i2c_setup_timing(i2c_dev, &i2c_dev->setup);
if (ret)
@ -2226,9 +2236,12 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
/* Setup Fast mode plus if necessary */
if (i2c_dev->bus_rate > I2C_MAX_FAST_MODE_FREQ) {
ret = stm32f7_i2c_setup_fm_plus_bits(pdev, i2c_dev);
if (ret)
return ret;
if (!i2c_dev->setup.fmp_cr1_bit) {
ret = stm32f7_i2c_setup_fm_plus_bits(pdev, i2c_dev);
if (ret)
return ret;
}
ret = stm32f7_i2c_write_fm_plus_bits(i2c_dev, true);
if (ret)
return ret;
@ -2507,6 +2520,7 @@ static const struct of_device_id stm32f7_i2c_match[] = {
{ .compatible = "st,stm32f7-i2c", .data = &stm32f7_setup},
{ .compatible = "st,stm32mp15-i2c", .data = &stm32mp15_setup},
{ .compatible = "st,stm32mp13-i2c", .data = &stm32mp13_setup},
{ .compatible = "st,stm32mp25-i2c", .data = &stm32mp25_setup},
{},
};
MODULE_DEVICE_TABLE(of, stm32f7_i2c_match);

View File

@ -70,7 +70,7 @@ static struct i2c_algo_bit_data bit_data = {
static struct i2c_adapter vt586b_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.name = "VIA i2c",
.algo_data = &bit_data,
};

View File

@ -304,7 +304,7 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter vt596_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
};

View File

@ -74,9 +74,6 @@
#define MCR_APB_96M 7
#define MCR_APB_166M 12
#define I2C_MODE_STANDARD 0
#define I2C_MODE_FAST 1
#define WMT_I2C_TIMEOUT (msecs_to_jiffies(1000))
struct wmt_i2c_dev {
@ -85,7 +82,7 @@ struct wmt_i2c_dev {
struct device *dev;
void __iomem *base;
struct clk *clk;
int mode;
u16 tcr;
int irq;
u16 cmd_status;
};
@ -109,6 +106,12 @@ static int wmt_i2c_wait_bus_not_busy(struct wmt_i2c_dev *i2c_dev)
static int wmt_check_status(struct wmt_i2c_dev *i2c_dev)
{
int ret = 0;
unsigned long wait_result;
wait_result = wait_for_completion_timeout(&i2c_dev->complete,
msecs_to_jiffies(500));
if (!wait_result)
return -ETIMEDOUT;
if (i2c_dev->cmd_status & ISR_NACK_ADDR)
ret = -EIO;
@ -119,21 +122,13 @@ static int wmt_check_status(struct wmt_i2c_dev *i2c_dev)
return ret;
}
static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg,
static int wmt_i2c_write(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg,
int last)
{
struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
u16 val, tcr_val;
u16 val, tcr_val = i2c_dev->tcr;
int ret;
unsigned long wait_result;
int xfer_len = 0;
if (!(pmsg->flags & I2C_M_NOSTART)) {
ret = wmt_i2c_wait_bus_not_busy(i2c_dev);
if (ret < 0)
return ret;
}
if (pmsg->len == 0) {
/*
* We still need to run through the while (..) once, so
@ -148,20 +143,12 @@ static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg,
if (!(pmsg->flags & I2C_M_NOSTART)) {
val = readw(i2c_dev->base + REG_CR);
val &= ~CR_TX_END;
writew(val, i2c_dev->base + REG_CR);
val = readw(i2c_dev->base + REG_CR);
val |= CR_CPU_RDY;
writew(val, i2c_dev->base + REG_CR);
}
reinit_completion(&i2c_dev->complete);
if (i2c_dev->mode == I2C_MODE_STANDARD)
tcr_val = TCR_STANDARD_MODE;
else
tcr_val = TCR_FAST_MODE;
tcr_val |= (TCR_MASTER_WRITE | (pmsg->addr & TCR_SLAVE_ADDR_MASK));
writew(tcr_val, i2c_dev->base + REG_TCR);
@ -173,12 +160,6 @@ static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg,
}
while (xfer_len < pmsg->len) {
wait_result = wait_for_completion_timeout(&i2c_dev->complete,
msecs_to_jiffies(500));
if (wait_result == 0)
return -ETIMEDOUT;
ret = wmt_check_status(i2c_dev);
if (ret)
return ret;
@ -210,48 +191,25 @@ static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg,
return 0;
}
static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg,
int last)
static int wmt_i2c_read(struct wmt_i2c_dev *i2c_dev, struct i2c_msg *pmsg)
{
struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
u16 val, tcr_val;
u16 val, tcr_val = i2c_dev->tcr;
int ret;
unsigned long wait_result;
u32 xfer_len = 0;
if (!(pmsg->flags & I2C_M_NOSTART)) {
ret = wmt_i2c_wait_bus_not_busy(i2c_dev);
if (ret < 0)
return ret;
}
val = readw(i2c_dev->base + REG_CR);
val &= ~CR_TX_END;
writew(val, i2c_dev->base + REG_CR);
val &= ~(CR_TX_END | CR_TX_NEXT_NO_ACK);
val = readw(i2c_dev->base + REG_CR);
val &= ~CR_TX_NEXT_NO_ACK;
writew(val, i2c_dev->base + REG_CR);
if (!(pmsg->flags & I2C_M_NOSTART)) {
val = readw(i2c_dev->base + REG_CR);
if (!(pmsg->flags & I2C_M_NOSTART))
val |= CR_CPU_RDY;
writew(val, i2c_dev->base + REG_CR);
}
if (pmsg->len == 1) {
val = readw(i2c_dev->base + REG_CR);
if (pmsg->len == 1)
val |= CR_TX_NEXT_NO_ACK;
writew(val, i2c_dev->base + REG_CR);
}
writew(val, i2c_dev->base + REG_CR);
reinit_completion(&i2c_dev->complete);
if (i2c_dev->mode == I2C_MODE_STANDARD)
tcr_val = TCR_STANDARD_MODE;
else
tcr_val = TCR_FAST_MODE;
tcr_val |= TCR_MASTER_READ | (pmsg->addr & TCR_SLAVE_ADDR_MASK);
writew(tcr_val, i2c_dev->base + REG_TCR);
@ -263,12 +221,6 @@ static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg,
}
while (xfer_len < pmsg->len) {
wait_result = wait_for_completion_timeout(&i2c_dev->complete,
msecs_to_jiffies(500));
if (!wait_result)
return -ETIMEDOUT;
ret = wmt_check_status(i2c_dev);
if (ret)
return ret;
@ -276,15 +228,10 @@ static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg,
pmsg->buf[xfer_len] = readw(i2c_dev->base + REG_CDR) >> 8;
xfer_len++;
if (xfer_len == pmsg->len - 1) {
val = readw(i2c_dev->base + REG_CR);
val |= (CR_TX_NEXT_NO_ACK | CR_CPU_RDY);
writew(val, i2c_dev->base + REG_CR);
} else {
val = readw(i2c_dev->base + REG_CR);
val |= CR_CPU_RDY;
writew(val, i2c_dev->base + REG_CR);
}
val = readw(i2c_dev->base + REG_CR) | CR_CPU_RDY;
if (xfer_len == pmsg->len - 1)
val |= CR_TX_NEXT_NO_ACK;
writew(val, i2c_dev->base + REG_CR);
}
return 0;
@ -295,17 +242,22 @@ static int wmt_i2c_xfer(struct i2c_adapter *adap,
int num)
{
struct i2c_msg *pmsg;
int i, is_last;
int i;
int ret = 0;
struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
for (i = 0; ret >= 0 && i < num; i++) {
is_last = ((i + 1) == num);
pmsg = &msgs[i];
if (!(pmsg->flags & I2C_M_NOSTART)) {
ret = wmt_i2c_wait_bus_not_busy(i2c_dev);
if (ret < 0)
return ret;
}
if (pmsg->flags & I2C_M_RD)
ret = wmt_i2c_read(adap, pmsg, is_last);
ret = wmt_i2c_read(i2c_dev, pmsg);
else
ret = wmt_i2c_write(adap, pmsg, is_last);
ret = wmt_i2c_write(i2c_dev, pmsg, (i + 1) == num);
}
return (ret < 0) ? ret : i;
@ -359,10 +311,10 @@ static int wmt_i2c_reset_hardware(struct wmt_i2c_dev *i2c_dev)
readw(i2c_dev->base + REG_CSR); /* read clear */
writew(ISR_WRITE_ALL, i2c_dev->base + REG_ISR);
if (i2c_dev->mode == I2C_MODE_STANDARD)
writew(SCL_TIMEOUT(128) | TR_STD, i2c_dev->base + REG_TR);
else
if (i2c_dev->tcr == TCR_FAST_MODE)
writew(SCL_TIMEOUT(128) | TR_HS, i2c_dev->base + REG_TR);
else
writew(SCL_TIMEOUT(128) | TR_STD, i2c_dev->base + REG_TR);
return 0;
}
@ -395,10 +347,9 @@ static int wmt_i2c_probe(struct platform_device *pdev)
return PTR_ERR(i2c_dev->clk);
}
i2c_dev->mode = I2C_MODE_STANDARD;
err = of_property_read_u32(np, "clock-frequency", &clk_rate);
if (!err && (clk_rate == I2C_MAX_FAST_MODE_FREQ))
i2c_dev->mode = I2C_MODE_FAST;
i2c_dev->tcr = TCR_FAST_MODE;
i2c_dev->dev = &pdev->dev;

View File

@ -427,7 +427,7 @@ static struct scx200_acb_iface *scx200_create_iface(const char *text,
snprintf(adapter->name, sizeof(adapter->name), "%s ACB%d", text, index);
adapter->owner = THIS_MODULE;
adapter->algo = &scx200_acb_algorithm;
adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adapter->class = I2C_CLASS_HWMON;
adapter->dev.parent = dev;
mutex_init(&iface->mutex);

View File

@ -16,6 +16,7 @@
#include <linux/acpi.h>
#include <linux/clk/clk-conf.h>
#include <linux/completion.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/errno.h>
@ -67,6 +68,8 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
static DEFINE_STATIC_KEY_FALSE(i2c_trace_msg_key);
static bool is_registered;
static struct dentry *i2c_debugfs_root;
int i2c_transfer_trace_reg(void)
{
static_branch_inc(&i2c_trace_msg_key);
@ -689,7 +692,7 @@ static struct attribute *i2c_dev_attrs[] = {
};
ATTRIBUTE_GROUPS(i2c_dev);
struct bus_type i2c_bus_type = {
const struct bus_type i2c_bus_type = {
.name = "i2c",
.match = i2c_device_match,
.probe = i2c_device_probe,
@ -1524,6 +1527,8 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
goto out_list;
}
adap->debugfs = debugfs_create_dir(dev_name(&adap->dev), i2c_debugfs_root);
res = i2c_setup_smbus_alert(adap);
if (res)
goto out_reg;
@ -1563,6 +1568,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
return 0;
out_reg:
debugfs_remove_recursive(adap->debugfs);
init_completion(&adap->dev_released);
device_unregister(&adap->dev);
wait_for_completion(&adap->dev_released);
@ -1764,6 +1770,8 @@ void i2c_del_adapter(struct i2c_adapter *adap)
i2c_host_notify_irq_teardown(adap);
debugfs_remove_recursive(adap->debugfs);
/* wait until all references to the device are gone
*
* FIXME: This is old code and should ideally be replaced by an
@ -2061,6 +2069,8 @@ static int __init i2c_init(void)
is_registered = true;
i2c_debugfs_root = debugfs_create_dir("i2c", NULL);
#ifdef CONFIG_I2C_COMPAT
i2c_adapter_compat_class = class_compat_register("i2c-adapter");
if (!i2c_adapter_compat_class) {
@ -2099,6 +2109,7 @@ static void __exit i2c_exit(void)
#ifdef CONFIG_I2C_COMPAT
class_compat_unregister(i2c_adapter_compat_class);
#endif
debugfs_remove_recursive(i2c_debugfs_root);
bus_unregister(&i2c_bus_type);
tracepoint_synchronize_unregister();
}

View File

@ -308,8 +308,8 @@ EXPORT_SYMBOL_GPL(i2c_free_slave_host_notify_device);
* target systems are the same.
* Restrictions to automatic SPD instantiation:
* - Only works if all filled slots have the same memory type
* - Only works for DDR2, DDR3 and DDR4 for now
* - Only works on systems with 1 to 4 memory slots
* - Only works for DDR, DDR2, DDR3 and DDR4 for now
* - Only works on systems with 1 to 8 memory slots
*/
#if IS_ENABLED(CONFIG_DMI)
void i2c_register_spd(struct i2c_adapter *adap)
@ -354,9 +354,9 @@ void i2c_register_spd(struct i2c_adapter *adap)
dev_info(&adap->dev, "%d/%d memory slots populated (from DMI)\n",
dimm_count, slot_count);
if (slot_count > 4) {
if (slot_count > 8) {
dev_warn(&adap->dev,
"Systems with more than 4 memory slots not supported yet, not instantiating SPD\n");
"Systems with more than 8 memory slots not supported yet, not instantiating SPD\n");
return;
}

View File

@ -308,7 +308,7 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter stub_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.algo = &smbus_algorithm,
.name = "SMBus stub driver",
};

View File

@ -159,7 +159,6 @@ static int i2c_mux_reg_probe(struct platform_device *pdev)
struct regmux *mux;
struct i2c_adapter *parent;
struct resource *res;
unsigned int class;
int i, ret, nr;
mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
@ -213,9 +212,8 @@ static int i2c_mux_reg_probe(struct platform_device *pdev)
for (i = 0; i < mux->data.n_values; i++) {
nr = mux->data.base_nr ? (mux->data.base_nr + i) : 0;
class = mux->data.classes ? mux->data.classes[i] : 0;
ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i], class);
ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i], 0);
if (ret)
goto err_del_mux_adapters;
}

View File

@ -289,7 +289,7 @@ static const struct i2c_algorithm netup_i2c_algorithm = {
static const struct i2c_adapter netup_i2c_adapter = {
.owner = THIS_MODULE,
.name = NETUP_UNIDVB_NAME,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.class = I2C_CLASS_HWMON,
.algo = &netup_i2c_algorithm,
};

View File

@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/nvmem-provider.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
@ -242,7 +243,7 @@ static const struct i2c_device_id at24_ids[] = {
};
MODULE_DEVICE_TABLE(i2c, at24_ids);
static const struct of_device_id at24_of_match[] = {
static const struct of_device_id __maybe_unused at24_of_match[] = {
{ .compatible = "atmel,24c00", .data = &at24_data_24c00 },
{ .compatible = "atmel,24c01", .data = &at24_data_24c01 },
{ .compatible = "atmel,24cs01", .data = &at24_data_24cs01 },
@ -835,7 +836,7 @@ static struct i2c_driver at24_driver = {
.driver = {
.name = "at24",
.pm = &at24_pm_ops,
.of_match_table = at24_of_match,
.of_match_table = of_match_ptr(at24_of_match),
.acpi_match_table = ACPI_PTR(at24_acpi_ids),
},
.probe = at24_probe,

View File

@ -264,7 +264,7 @@ static int gb_i2c_probe(struct gbphy_device *gbphy_dev,
/* Looks good; up our i2c adapter */
adapter = &gb_i2c_dev->adapter;
adapter->owner = THIS_MODULE;
adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adapter->class = I2C_CLASS_HWMON;
adapter->algo = &gb_i2c_algorithm;
adapter->dev.parent = &gbphy_dev->dev;

View File

@ -116,7 +116,6 @@ unsigned char *fb_ddc_read(struct i2c_adapter *adapter)
algo_data->setsda(algo_data->data, 1);
algo_data->setscl(algo_data->data, 1);
adapter->class |= I2C_CLASS_DDC;
return edid;
}

View File

@ -1227,7 +1227,6 @@ static int cyber2000fb_setup_ddc_bus(struct cfb_info *cfb)
strscpy(cfb->ddc_adapter.name, cfb->fb.fix.id,
sizeof(cfb->ddc_adapter.name));
cfb->ddc_adapter.owner = THIS_MODULE;
cfb->ddc_adapter.class = I2C_CLASS_DDC;
cfb->ddc_adapter.algo_data = &cfb->ddc_algo;
cfb->ddc_adapter.dev.parent = cfb->fb.device;
cfb->ddc_algo.setsda = cyber2000fb_ddc_setsda;

View File

@ -163,7 +163,6 @@ static int i740fb_setup_ddc_bus(struct fb_info *info)
strscpy(par->ddc_adapter.name, info->fix.id,
sizeof(par->ddc_adapter.name));
par->ddc_adapter.owner = THIS_MODULE;
par->ddc_adapter.class = I2C_CLASS_DDC;
par->ddc_adapter.algo_data = &par->ddc_algo;
par->ddc_adapter.dev.parent = info->device;
par->ddc_algo.setsda = i740fb_ddc_setsda;

View File

@ -100,8 +100,7 @@ static const struct i2c_algo_bit_data matrox_i2c_algo_template =
};
static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo,
unsigned int data, unsigned int clock, const char *name,
int class)
unsigned int data, unsigned int clock, const char *name)
{
int err;
@ -112,7 +111,6 @@ static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo,
snprintf(b->adapter.name, sizeof(b->adapter.name), name,
minfo->fbcon.node);
i2c_set_adapdata(&b->adapter, b);
b->adapter.class = class;
b->adapter.algo_data = &b->bac;
b->adapter.dev.parent = &minfo->pcidev->dev;
b->bac = matrox_i2c_algo_template;
@ -160,27 +158,24 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) {
case MGA_2164:
err = i2c_bus_reg(&m2info->ddc1, minfo,
DDC1B_DATA, DDC1B_CLK,
"DDC:fb%u #0", I2C_CLASS_DDC);
"DDC:fb%u #0");
break;
default:
err = i2c_bus_reg(&m2info->ddc1, minfo,
DDC1_DATA, DDC1_CLK,
"DDC:fb%u #0", I2C_CLASS_DDC);
"DDC:fb%u #0");
break;
}
if (err)
goto fail_ddc1;
if (minfo->devflags.dualhead) {
err = i2c_bus_reg(&m2info->ddc2, minfo,
DDC2_DATA, DDC2_CLK,
"DDC:fb%u #1", I2C_CLASS_DDC);
err = i2c_bus_reg(&m2info->ddc2, minfo, DDC2_DATA, DDC2_CLK, "DDC:fb%u #1");
if (err == -ENODEV) {
printk(KERN_INFO "i2c-matroxfb: VGA->TV plug detected, DDC unavailable.\n");
} else if (err)
printk(KERN_INFO "i2c-matroxfb: Could not register secondary output i2c bus. Continuing anyway.\n");
/* Register maven bus even on G450/G550 */
err = i2c_bus_reg(&m2info->maven, minfo,
MAT_DATA, MAT_CLK, "MAVEN:fb%u", 0);
err = i2c_bus_reg(&m2info->maven, minfo, MAT_DATA, MAT_CLK, "MAVEN:fb%u");
if (err)
printk(KERN_INFO "i2c-matroxfb: Could not register Maven i2c bus. Continuing anyway.\n");
else {

View File

@ -252,7 +252,6 @@ static int s3fb_setup_ddc_bus(struct fb_info *info)
strscpy(par->ddc_adapter.name, info->fix.id,
sizeof(par->ddc_adapter.name));
par->ddc_adapter.owner = THIS_MODULE;
par->ddc_adapter.class = I2C_CLASS_DDC;
par->ddc_adapter.algo_data = &par->ddc_algo;
par->ddc_adapter.dev.parent = info->device;
par->ddc_algo.setsda = s3fb_ddc_setsda;

View File

@ -1267,7 +1267,6 @@ static int tdfxfb_setup_ddc_bus(struct tdfxfb_i2c_chan *chan, const char *name,
strscpy(chan->adapter.name, name, sizeof(chan->adapter.name));
chan->adapter.owner = THIS_MODULE;
chan->adapter.class = I2C_CLASS_DDC;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = dev;
chan->algo.setsda = tdfxfb_ddc_setsda;

View File

@ -274,7 +274,6 @@ static int tridentfb_setup_ddc_bus(struct fb_info *info)
strscpy(par->ddc_adapter.name, info->fix.id,
sizeof(par->ddc_adapter.name));
par->ddc_adapter.owner = THIS_MODULE;
par->ddc_adapter.class = I2C_CLASS_DDC;
par->ddc_adapter.algo_data = &par->ddc_algo;
par->ddc_adapter.dev.parent = info->device;
if (is_oldclock(par->chip_id)) { /* not sure if this check is OK */

View File

@ -201,7 +201,6 @@ static int create_i2c_bus(struct i2c_adapter *adapter,
sprintf(adapter->name, "viafb i2c io_port idx 0x%02x",
adap_cfg->ioport_index);
adapter->owner = THIS_MODULE;
adapter->class = I2C_CLASS_DDC;
adapter->algo_data = algo;
if (pdev)
adapter->dev.parent = &pdev->dev;

View File

@ -23,7 +23,7 @@
#include <linux/swab.h> /* for swab16 */
#include <uapi/linux/i2c.h>
extern struct bus_type i2c_bus_type;
extern const struct bus_type i2c_bus_type;
extern struct device_type i2c_adapter_type;
extern struct device_type i2c_client_type;
@ -746,6 +746,8 @@ struct i2c_adapter {
struct irq_domain *host_notify_domain;
struct regulator *bus_regulator;
struct dentry *debugfs;
};
#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
@ -850,7 +852,6 @@ static inline void i2c_mark_adapter_resumed(struct i2c_adapter *adap)
/* i2c adapter classes (bitmask) */
#define I2C_CLASS_HWMON (1<<0) /* lm_sensors, ... */
#define I2C_CLASS_DDC (1<<3) /* DDC bus on graphics adapters */
#define I2C_CLASS_SPD (1<<7) /* Memory modules */
/* Warn users that the adapter doesn't support classes anymore */
#define I2C_CLASS_DEPRECATED (1<<8)

View File

@ -17,7 +17,6 @@
* @n_values: Number of multiplexer channels
* @little_endian: Indicating if the register is in little endian
* @write_only: Reading the register is not allowed by hardware
* @classes: Optional I2C auto-detection classes
* @idle: Value to write to mux when idle
* @idle_in_use: indicate if idle value is in use
* @reg: Virtual address of the register to switch channel
@ -30,7 +29,6 @@ struct i2c_mux_reg_platform_data {
int n_values;
bool little_endian;
bool write_only;
const unsigned int *classes;
u32 idle;
bool idle_in_use;
void __iomem *reg;

View File

@ -446,7 +446,7 @@ static const struct rockchip_sound_route rockchip_routes[] = {
struct dailink_match_data {
const char *compatible;
struct bus_type *bus_type;
const struct bus_type *bus_type;
};
static const struct dailink_match_data dailink_match[] = {