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

Pull i2c updates from Wolfram Sang:
 "I2C has largely driver updates for 6.7, i.e. feature additions (like
  adding transfers while in atomic mode), using new helpers (like
  devm_clk_get_enabled), new IDs, documentation fixes and additions...
  you name it.

  The core got a memleak fix and better support for nested muxes"

* tag 'i2c-for-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (53 commits)
  i2c: s3c2410: make i2c_s3c_irq_nextbyte() void
  i2c: qcom-geni: add ACPI device id for sc8180x
  Documentation: i2c: add fault code for not supporting 10 bit addresses
  i2c: sun6i-p2wi: Prevent potential division by zero
  i2c: mux: demux-pinctrl: Convert to use sysfs_emit_at() API
  i2c: i801: Use new helper acpi_use_parent_companion
  ACPI: Add helper acpi_use_parent_companion
  MAINTAINERS: add YAML file for i2c-demux-pinctrl
  i2c: core: fix lockdep warning for sparsely nested adapter chain
  i2c: axxia: eliminate kernel-doc warnings
  dt-bindings: i2c: i2c-demux-pinctrl: Convert to json-schema
  i2c: stm32f7: Use devm_clk_get_enabled()
  i2c: stm32f4: Use devm_clk_get_enabled()
  i2c: stm32f7: add description of atomic in struct stm32f7_i2c_dev
  i2c: fix memleak in i2c_new_client_device()
  i2c: exynos5: Calculate t_scl_l, t_scl_h according to i2c spec
  i2c: i801: Simplify class-based client device instantiation
  i2c: exynos5: add support for atomic transfers
  i2c: at91-core: Use devm_clk_get_enabled()
  eeprom: at24: add ST M24C64-D Additional Write lockable page support
  ...
This commit is contained in:
Linus Torvalds
2023-11-05 08:41:14 -10:00
34 changed files with 596 additions and 427 deletions

View File

@@ -68,10 +68,14 @@ properties:
pattern: cs16$
- items:
pattern: c32$
- items:
pattern: c32d-wl$
- items:
pattern: cs32$
- items:
pattern: c64$
- items:
pattern: c64d-wl$
- items:
pattern: cs64$
- items:

View File

@@ -1,135 +0,0 @@
Pinctrl-based I2C Bus DeMux
This binding describes an I2C bus demultiplexer that uses pin multiplexing to
route the I2C signals, and represents the pin multiplexing configuration using
the pinctrl device tree bindings. This may be used to select one I2C IP core at
runtime which may have a better feature set for a given task than another I2C
IP core on the SoC. The most simple example is to fall back to GPIO bitbanging
if your current runtime configuration hits an errata of the internal IP core.
+-------------------------------+
| SoC |
| | +-----+ +-----+
| +------------+ | | dev | | dev |
| |I2C IP Core1|--\ | +-----+ +-----+
| +------------+ \-------+ | | |
| |Pinctrl|--|------+--------+
| +------------+ +-------+ |
| |I2C IP Core2|--/ |
| +------------+ |
| |
+-------------------------------+
Required properties:
- compatible: "i2c-demux-pinctrl"
- i2c-parent: List of phandles of I2C masters available for selection. The first
one will be used as default.
- i2c-bus-name: The name of this bus. Also needed as pinctrl-name for the I2C
parents.
Furthermore, I2C mux properties and child nodes. See i2c-mux.yaml in this
directory.
Example:
Here is a snipplet for a bus to be demuxed. It contains various i2c clients for
HDMI, so the bus is named "i2c-hdmi":
i2chdmi: i2c@8 {
compatible = "i2c-demux-pinctrl";
i2c-parent = <&gpioi2c>, <&iic2>, <&i2c2>;
i2c-bus-name = "i2c-hdmi";
#address-cells = <1>;
#size-cells = <0>;
ak4643: sound-codec@12 {
compatible = "asahi-kasei,ak4643";
#sound-dai-cells = <0>;
reg = <0x12>;
};
composite-in@20 {
compatible = "adi,adv7180";
reg = <0x20>;
remote = <&vin1>;
port {
adv7180: endpoint {
bus-width = <8>;
remote-endpoint = <&vin1ep0>;
};
};
};
hdmi@39 {
compatible = "adi,adv7511w";
reg = <0x39>;
interrupt-parent = <&gpio1>;
interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
adi,input-depth = <8>;
adi,input-colorspace = "rgb";
adi,input-clock = "1x";
adi,input-style = <1>;
adi,input-justification = "evenly";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
adv7511_in: endpoint {
remote-endpoint = <&du_out_lvds0>;
};
};
port@1 {
reg = <1>;
adv7511_out: endpoint {
remote-endpoint = <&hdmi_con>;
};
};
};
};
};
And for clarification, here are the snipplets for the i2c-parents:
gpioi2c: i2c@9 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "i2c-gpio";
gpios = <&gpio5 6 GPIO_ACTIVE_HIGH /* sda */
&gpio5 5 GPIO_ACTIVE_HIGH /* scl */
>;
i2c-gpio,delay-us = <5>;
};
...
&i2c2 {
pinctrl-0 = <&i2c2_pins>;
pinctrl-names = "i2c-hdmi";
clock-frequency = <100000>;
};
...
&iic2 {
pinctrl-0 = <&iic2_pins>;
pinctrl-names = "i2c-hdmi";
clock-frequency = <100000>;
};
Please note:
- pinctrl properties for the parent I2C controllers need a pinctrl state
with the same name as i2c-bus-name, not "default"!
- the i2c masters must have their status "disabled". This driver will
enable them at runtime when needed.

View File

@@ -0,0 +1,172 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/i2c/i2c-demux-pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Pinctrl-based I2C Bus Demultiplexer
maintainers:
- Wolfram Sang <wsa+renesas@sang-engineering.com>
description: |
This binding describes an I2C bus demultiplexer that uses pin multiplexing to
route the I2C signals, and represents the pin multiplexing configuration
using the pinctrl device tree bindings. This may be used to select one I2C
IP core at runtime which may have a better feature set for a given task than
another I2C IP core on the SoC. The most simple example is to fall back to
GPIO bitbanging if your current runtime configuration hits an errata of the
internal IP core.
+-------------------------------+
| SoC |
| | +-----+ +-----+
| +------------+ | | dev | | dev |
| |I2C IP Core1|--\ | +-----+ +-----+
| +------------+ \-------+ | | |
| |Pinctrl|--|------+--------+
| +------------+ +-------+ |
| |I2C IP Core2|--/ |
| +------------+ |
| |
+-------------------------------+
allOf:
- $ref: i2c-mux.yaml
- $ref: /schemas/i2c/i2c-controller.yaml#
properties:
compatible:
const: i2c-demux-pinctrl
i2c-parent:
$ref: /schemas/types.yaml#/definitions/phandle-array
description:
List of phandles of I2C masters available for selection. The first one
will be used as default.
i2c-bus-name:
$ref: /schemas/types.yaml#/definitions/string
description:
The name of this bus. Also needed as pinctrl-name for the I2C parents.
required:
- compatible
- i2c-parent
- i2c-bus-name
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
gpioi2c2: i2c-9 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "i2c-gpio";
scl-gpios = <&gpio5 5 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
sda-gpios = <&gpio5 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
i2c-gpio,delay-us = <5>;
// The I2C controller must have its status "disabled". The I2C bus
// demultiplexer will enable it at runtime when needed.
status = "disabled";
};
iic2: i2c@e6520000 {
reg = <0xe6520000 0x425>;
pinctrl-0 = <&iic2_pins>;
// The pinctrl property for the parent I2C controller needs a pinctrl
// state with the same name as i2c-bus-name in the I2C bus demultiplexer
// node, not "default"!
pinctrl-names = "i2c-hdmi";
clock-frequency = <100000>;
// The I2C controller must have its status "disabled". The I2C bus
// demultiplexer will enable it at runtime when needed.
status = "disabled";
};
i2c2: i2c@e6530000 {
reg = <0 0xe6530000 0 0x40>;
pinctrl-0 = <&i2c2_pins>;
// The pinctrl property for the parent I2C controller needs a pinctrl
// state with the same name as i2c-bus-name in the I2C bus demultiplexer
// node, not "default"!
pinctrl-names = "i2c-hdmi";
clock-frequency = <100000>;
// The I2C controller must have its status "disabled". The I2C bus
// demultiplexer will enable it at runtime when needed.
status = "disabled";
};
// Example for a bus to be demuxed. It contains various I2C clients for
// HDMI, so the bus is named "i2c-hdmi":
i2chdmi: i2c-mux3 {
compatible = "i2c-demux-pinctrl";
i2c-parent = <&iic2>, <&i2c2>, <&gpioi2c2>;
i2c-bus-name = "i2c-hdmi";
#address-cells = <1>;
#size-cells = <0>;
ak4643: codec@12 {
compatible = "asahi-kasei,ak4643";
#sound-dai-cells = <0>;
reg = <0x12>;
};
composite-in@20 {
compatible = "adi,adv7180";
reg = <0x20>;
port {
adv7180: endpoint {
bus-width = <8>;
remote-endpoint = <&vin1ep0>;
};
};
};
hdmi@39 {
compatible = "adi,adv7511w";
reg = <0x39>;
interrupt-parent = <&gpio1>;
interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
clocks = <&cec_clock>;
clock-names = "cec";
avdd-supply = <&fixedregulator1v8>;
dvdd-supply = <&fixedregulator1v8>;
pvdd-supply = <&fixedregulator1v8>;
dvdd-3v-supply = <&fixedregulator3v3>;
bgvdd-supply = <&fixedregulator1v8>;
adi,input-depth = <8>;
adi,input-colorspace = "rgb";
adi,input-clock = "1x";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
adv7511_in: endpoint {
remote-endpoint = <&lvds0_out>;
};
};
port@1 {
reg = <1>;
adv7511_out: endpoint {
remote-endpoint = <&hdmi_con_out>;
};
};
};
};
};

View File

@@ -25,6 +25,7 @@ properties:
- items:
- enum:
- qcom,sc7280-cci
- qcom,sdm845-cci
- qcom,sm6350-cci
- qcom,sm8250-cci
@@ -159,6 +160,7 @@ allOf:
compatible:
contains:
enum:
- qcom,sc7280-cci
- qcom,sm8250-cci
- qcom,sm8450-cci
then:

View File

@@ -47,6 +47,7 @@ Supported adapters:
* Intel Alder Lake (PCH)
* Intel Raptor Lake (PCH)
* Intel Meteor Lake (SOC and PCH)
* Intel Birch Stream (SOC)
Datasheets: Publicly available at the Intel website

View File

@@ -39,6 +39,10 @@ Also, codes returned by adapter probe methods follow rules which are
specific to their host bus (such as PCI, or the platform bus).
EAFNOSUPPORT
Returned by I2C adapters not supporting 10 bit addresses when
they are requested to use such an address.
EAGAIN
Returned by I2C adapters when they lose arbitration in master
transmit mode: some other master was transmitting different

View File

@@ -8825,6 +8825,7 @@ F: include/linux/phy/
GENERIC PINCTRL I2C DEMULTIPLEXER DRIVER
M: Wolfram Sang <wsa+renesas@sang-engineering.com>
S: Supported
F: Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.yaml
F: drivers/i2c/muxes/i2c-demux-pinctrl.c
GENERIC PM DOMAINS

View File

@@ -158,6 +158,7 @@ config I2C_I801
Alder Lake (PCH)
Raptor Lake (PCH)
Meteor Lake (SOC and PCH)
Birch Stream (SOC)
This driver can also be built as a module. If so, the module
will be called i2c-i801.

View File

@@ -221,11 +221,10 @@ static int at91_twi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, dev);
dev->clk = devm_clk_get(dev->dev, NULL);
dev->clk = devm_clk_get_enabled(dev->dev, NULL);
if (IS_ERR(dev->clk))
return dev_err_probe(dev->dev, PTR_ERR(dev->clk), "no clock defined\n");
clk_prepare_enable(dev->clk);
return dev_err_probe(dev->dev, PTR_ERR(dev->clk),
"failed to enable clock\n");
snprintf(dev->adapter.name, sizeof(dev->adapter.name), "AT91");
i2c_set_adapdata(&dev->adapter, dev);
@@ -254,8 +253,6 @@ static int at91_twi_probe(struct platform_device *pdev)
rc = i2c_add_numbered_adapter(&dev->adapter);
if (rc) {
clk_disable_unprepare(dev->clk);
pm_runtime_disable(dev->dev);
pm_runtime_set_suspended(dev->dev);
@@ -272,7 +269,6 @@ static void at91_twi_remove(struct platform_device *pdev)
struct at91_twi_dev *dev = platform_get_drvdata(pdev);
i2c_del_adapter(&dev->adapter);
clk_disable_unprepare(dev->clk);
pm_runtime_disable(dev->dev);
pm_runtime_set_suspended(dev->dev);

View File

@@ -131,6 +131,8 @@
* @i2c_clk: clock reference for i2c input clock
* @bus_clk_rate: current i2c bus clock rate
* @last: a flag indicating is this is last message in transfer
* @slave: associated &i2c_client
* @irq: platform device IRQ number
*/
struct axxia_i2c_dev {
void __iomem *base;
@@ -165,7 +167,7 @@ static void i2c_int_enable(struct axxia_i2c_dev *idev, u32 mask)
writel(int_en | mask, idev->base + MST_INT_ENABLE);
}
/**
/*
* ns_to_clk - Convert time (ns) to clock cycles for the given clock frequency.
*/
static u32 ns_to_clk(u64 ns, u32 clk_mhz)
@@ -263,7 +265,7 @@ static int i2c_m_recv_len(const struct i2c_msg *msg)
return (msg->flags & I2C_M_RECV_LEN) != 0;
}
/**
/*
* axxia_i2c_empty_rx_fifo - Fetch data from RX FIFO and update SMBus block
* transfer length if this is the first byte of such a transfer.
*/
@@ -295,7 +297,7 @@ static int axxia_i2c_empty_rx_fifo(struct axxia_i2c_dev *idev)
return 0;
}
/**
/*
* axxia_i2c_fill_tx_fifo - Fill TX FIFO from current message buffer.
* @return: Number of bytes left to transfer.
*/

View File

@@ -160,6 +160,7 @@ struct brcmstb_i2c_dev {
struct completion done;
u32 clk_freq_hz;
int data_regsz;
bool atomic;
};
/* register accessors for both be and le cpu arch */
@@ -240,7 +241,7 @@ static int brcmstb_i2c_wait_for_completion(struct brcmstb_i2c_dev *dev)
int ret = 0;
unsigned long timeout = msecs_to_jiffies(I2C_TIMEOUT);
if (dev->irq >= 0) {
if (dev->irq >= 0 && !dev->atomic) {
if (!wait_for_completion_timeout(&dev->done, timeout))
ret = -ETIMEDOUT;
} else {
@@ -287,7 +288,7 @@ static int brcmstb_send_i2c_cmd(struct brcmstb_i2c_dev *dev,
return rc;
/* only if we are in interrupt mode */
if (dev->irq >= 0)
if (dev->irq >= 0 && !dev->atomic)
reinit_completion(&dev->done);
/* enable BSC CTL interrupt line */
@@ -520,6 +521,23 @@ out:
}
static int brcmstb_i2c_xfer_atomic(struct i2c_adapter *adapter,
struct i2c_msg msgs[], int num)
{
struct brcmstb_i2c_dev *dev = i2c_get_adapdata(adapter);
int ret;
if (dev->irq >= 0)
disable_irq(dev->irq);
dev->atomic = true;
ret = brcmstb_i2c_xfer(adapter, msgs, num);
dev->atomic = false;
if (dev->irq >= 0)
enable_irq(dev->irq);
return ret;
}
static u32 brcmstb_i2c_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR
@@ -528,6 +546,7 @@ static u32 brcmstb_i2c_functionality(struct i2c_adapter *adap)
static const struct i2c_algorithm brcmstb_i2c_algo = {
.master_xfer = brcmstb_i2c_xfer,
.master_xfer_atomic = brcmstb_i2c_xfer_atomic,
.functionality = brcmstb_i2c_functionality,
};

View File

@@ -298,7 +298,7 @@ cp2615_i2c_probe(struct usb_interface *usbif, const struct usb_device_id *id)
if (!adap)
return -ENOMEM;
strncpy(adap->name, usbdev->serial, sizeof(adap->name) - 1);
strscpy(adap->name, usbdev->serial, sizeof(adap->name));
adap->owner = THIS_MODULE;
adap->dev.parent = &usbif->dev;
adap->dev.of_node = usbif->dev.of_node;

View File

@@ -194,6 +194,11 @@ struct exynos5_i2c {
*/
int trans_done;
/*
* Called from atomic context, don't use interrupts.
*/
unsigned int atomic;
/* Controller operating frequency */
unsigned int op_clock;
@@ -265,7 +270,7 @@ static void exynos5_i2c_clr_pend_irq(struct exynos5_i2c *i2c)
* exynos5_i2c_set_timing: updates the registers with appropriate
* timing values calculated
*
* Timing values for operation are calculated against either 100kHz
* Timing values for operation are calculated against 100kHz, 400kHz
* or 1MHz controller operating frequency.
*
* Returns 0 on success, -EINVAL if the cycle length cannot
@@ -328,6 +333,23 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, bool hs_timings)
*
* Constraints: 4 <= temp, 0 <= CLK_DIV < 256, 2 <= clk_cycle <= 510
*
* To split SCL clock into low, high periods appropriately, one
* proportion factor for each I2C mode is used, which is calculated
* using this formula.
* ```
* ((t_low_min + (scl_clock - t_low_min - t_high_min) / 2) / scl_clock)
* ```
* where:
* t_low_min is the minimal value of low period of the SCL clock in us;
* t_high_min is the minimal value of high period of the SCL clock in us;
* scl_clock is converted from SCL clock frequency into us.
*
* Below are the proportion factors for these I2C modes:
* t_low_min, t_high_min, scl_clock, proportion
* Standard Mode: 4.7us, 4.0us, 10us, 0.535
* Fast Mode: 1.3us, 0.6us, 2.5us, 0.64
* Fast-Plus Mode: 0.5us, 0.26us, 1us, 0.62
*
*/
t_ftl_cycle = (readl(i2c->regs + HSI2C_CONF) >> 16) & 0x7;
temp = clkin / op_clk - 8 - t_ftl_cycle;
@@ -341,8 +363,19 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, bool hs_timings)
return -EINVAL;
}
t_scl_l = clk_cycle / 2;
t_scl_h = clk_cycle / 2;
/*
* Scale clk_cycle to get t_scl_l using the proption factors for individual I2C modes.
*/
if (op_clk <= I2C_MAX_STANDARD_MODE_FREQ)
t_scl_l = clk_cycle * 535 / 1000;
else if (op_clk <= I2C_MAX_FAST_MODE_FREQ)
t_scl_l = clk_cycle * 64 / 100;
else
t_scl_l = clk_cycle * 62 / 100;
if (t_scl_l > 0xFF)
t_scl_l = 0xFF;
t_scl_h = clk_cycle - t_scl_l;
t_start_su = t_scl_l;
t_start_hd = t_scl_l;
t_stop_su = t_scl_l;
@@ -711,6 +744,22 @@ static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop)
spin_unlock_irqrestore(&i2c->lock, flags);
}
static bool exynos5_i2c_poll_irqs_timeout(struct exynos5_i2c *i2c,
unsigned long timeout)
{
unsigned long time_left = jiffies + timeout;
while (time_before(jiffies, time_left) &&
!((i2c->trans_done && (i2c->msg->len == i2c->msg_ptr)) ||
(i2c->state < 0))) {
while (readl(i2c->regs + HSI2C_INT_ENABLE) &
readl(i2c->regs + HSI2C_INT_STATUS))
exynos5_i2c_irq(i2c->irq, i2c);
usleep_range(100, 200);
}
return time_before(jiffies, time_left);
}
static int exynos5_i2c_xfer_msg(struct exynos5_i2c *i2c,
struct i2c_msg *msgs, int stop)
{
@@ -725,8 +774,13 @@ static int exynos5_i2c_xfer_msg(struct exynos5_i2c *i2c,
exynos5_i2c_message_start(i2c, stop);
timeout = wait_for_completion_timeout(&i2c->msg_complete,
EXYNOS5_I2C_TIMEOUT);
if (!i2c->atomic)
timeout = wait_for_completion_timeout(&i2c->msg_complete,
EXYNOS5_I2C_TIMEOUT);
else
timeout = exynos5_i2c_poll_irqs_timeout(i2c,
EXYNOS5_I2C_TIMEOUT);
if (timeout == 0)
ret = -ETIMEDOUT;
else
@@ -777,6 +831,21 @@ err_pclk:
return ret ?: num;
}
static int exynos5_i2c_xfer_atomic(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num)
{
struct exynos5_i2c *i2c = adap->algo_data;
int ret;
disable_irq(i2c->irq);
i2c->atomic = true;
ret = exynos5_i2c_xfer(adap, msgs, num);
i2c->atomic = false;
enable_irq(i2c->irq);
return ret;
}
static u32 exynos5_i2c_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
@@ -784,6 +853,7 @@ static u32 exynos5_i2c_func(struct i2c_adapter *adap)
static const struct i2c_algorithm exynos5_i2c_algorithm = {
.master_xfer = exynos5_i2c_xfer,
.master_xfer_atomic = exynos5_i2c_xfer_atomic,
.functionality = exynos5_i2c_func,
};

View File

@@ -263,15 +263,10 @@ static void i2c_gpio_fault_injector_init(struct platform_device *pdev)
* 'fault-injector' dir there. Until then, we have a global dir with
* all adapters as subdirs.
*/
if (!i2c_gpio_debug_dir) {
if (!i2c_gpio_debug_dir)
i2c_gpio_debug_dir = debugfs_create_dir("i2c-fault-injector", NULL);
if (!i2c_gpio_debug_dir)
return;
}
priv->debug_dir = debugfs_create_dir(pdev->name, i2c_gpio_debug_dir);
if (!priv->debug_dir)
return;
init_completion(&priv->scl_irq_completion);

View File

@@ -79,6 +79,7 @@
* Meteor Lake-P (SOC) 0x7e22 32 hard yes yes yes
* Meteor Lake SoC-S (SOC) 0xae22 32 hard yes yes yes
* Meteor Lake PCH-S (PCH) 0x7f23 32 hard yes yes yes
* Birch Stream (SOC) 0x5796 32 hard yes yes yes
*
* Features supported by this driver:
* Software PEC no
@@ -231,6 +232,7 @@
#define PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS 0x4da3
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_P_SMBUS 0x51a3
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_M_SMBUS 0x54a3
#define PCI_DEVICE_ID_INTEL_BIRCH_STREAM_SMBUS 0x5796
#define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4
#define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_S_SMBUS 0x7a23
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS 0x7aa3
@@ -285,7 +287,6 @@ struct i801_priv {
u8 *data;
#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
const struct i801_mux_config *mux_drvdata;
struct platform_device *mux_pdev;
struct gpiod_lookup_table *lookup;
#endif
@@ -293,10 +294,9 @@ struct i801_priv {
/*
* If set to true the host controller registers are reserved for
* ACPI AML use. Protected by acpi_lock.
* ACPI AML use.
*/
bool acpi_reserved;
struct mutex acpi_lock;
};
#define FEATURE_SMBUS_PEC BIT(0)
@@ -679,15 +679,11 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
return result ? priv->status : -ETIMEDOUT;
}
if (len == 1 && read_write == I2C_SMBUS_READ)
smbcmd |= SMBHSTCNT_LAST_BYTE;
outb_p(smbcmd | SMBHSTCNT_START, SMBHSTCNT(priv));
for (i = 1; i <= len; i++) {
if (i == len && read_write == I2C_SMBUS_READ)
smbcmd |= SMBHSTCNT_LAST_BYTE;
outb_p(smbcmd, SMBHSTCNT(priv));
if (i == 1)
outb_p(inb(SMBHSTCNT(priv)) | SMBHSTCNT_START,
SMBHSTCNT(priv));
status = i801_wait_byte_done(priv);
if (status)
return status;
@@ -710,9 +706,12 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
data->block[0] = len;
}
/* Retrieve/store value in SMBBLKDAT */
if (read_write == I2C_SMBUS_READ)
if (read_write == I2C_SMBUS_READ) {
data->block[i] = inb_p(SMBBLKDAT(priv));
if (i == len - 1)
outb_p(smbcmd | SMBHSTCNT_LAST_BYTE, SMBHSTCNT(priv));
}
if (read_write == I2C_SMBUS_WRITE && i+1 <= len)
outb_p(data->block[i+1], SMBBLKDAT(priv));
@@ -875,11 +874,8 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
int hwpec, ret;
struct i801_priv *priv = i2c_get_adapdata(adap);
mutex_lock(&priv->acpi_lock);
if (priv->acpi_reserved) {
mutex_unlock(&priv->acpi_lock);
if (priv->acpi_reserved)
return -EBUSY;
}
pm_runtime_get_sync(&priv->pci_dev->dev);
@@ -920,7 +916,6 @@ out:
pm_runtime_mark_last_busy(&priv->pci_dev->dev);
pm_runtime_put_autosuspend(&priv->pci_dev->dev);
mutex_unlock(&priv->acpi_lock);
return ret;
}
@@ -1044,6 +1039,7 @@ static const struct pci_device_id i801_ids[] = {
{ PCI_DEVICE_DATA(INTEL, METEOR_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ PCI_DEVICE_DATA(INTEL, METEOR_LAKE_SOC_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ PCI_DEVICE_DATA(INTEL, METEOR_LAKE_PCH_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ PCI_DEVICE_DATA(INTEL, BIRCH_STREAM_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) },
{ 0, }
};
@@ -1288,7 +1284,7 @@ static void i801_probe_optional_slaves(struct i801_priv *priv)
/* Instantiate SPD EEPROMs unless the SMBus is multiplexed */
#if IS_ENABLED(CONFIG_I2C_MUX_GPIO)
if (!priv->mux_drvdata)
if (!priv->mux_pdev)
#endif
i2c_register_spd(&priv->adapter);
}
@@ -1390,11 +1386,14 @@ static void i801_add_mux(struct i801_priv *priv)
const struct i801_mux_config *mux_config;
struct i2c_mux_gpio_platform_data gpio_data;
struct gpiod_lookup_table *lookup;
const struct dmi_system_id *id;
int i;
if (!priv->mux_drvdata)
id = dmi_first_match(mux_dmi_table);
if (!id)
return;
mux_config = priv->mux_drvdata;
mux_config = id->driver_data;
/* Prepare the platform data */
memset(&gpio_data, 0, sizeof(struct i2c_mux_gpio_platform_data));
@@ -1438,35 +1437,9 @@ static void i801_del_mux(struct i801_priv *priv)
platform_device_unregister(priv->mux_pdev);
gpiod_remove_lookup_table(priv->lookup);
}
static unsigned int i801_get_adapter_class(struct i801_priv *priv)
{
const struct dmi_system_id *id;
const struct i801_mux_config *mux_config;
unsigned int class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
int i;
id = dmi_first_match(mux_dmi_table);
if (id) {
/* Remove branch classes from trunk */
mux_config = id->driver_data;
for (i = 0; i < mux_config->n_values; i++)
class &= ~mux_config->classes[i];
/* Remember for later */
priv->mux_drvdata = mux_config;
}
return class;
}
#else
static inline void i801_add_mux(struct i801_priv *priv) { }
static inline void i801_del_mux(struct i801_priv *priv) { }
static inline unsigned int i801_get_adapter_class(struct i801_priv *priv)
{
return I2C_CLASS_HWMON | I2C_CLASS_SPD;
}
#endif
static struct platform_device *
@@ -1572,7 +1545,7 @@ i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
* further access from the driver itself. This device is now owned
* by the system firmware.
*/
mutex_lock(&priv->acpi_lock);
i2c_lock_bus(&priv->adapter, I2C_LOCK_SEGMENT);
if (!priv->acpi_reserved && i801_acpi_is_smbus_ioport(priv, address)) {
priv->acpi_reserved = true;
@@ -1592,7 +1565,7 @@ i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
else
status = acpi_os_write_port(address, (u32)*value, bits);
mutex_unlock(&priv->acpi_lock);
i2c_unlock_bus(&priv->adapter, I2C_LOCK_SEGMENT);
return status;
}
@@ -1630,6 +1603,12 @@ static void i801_setup_hstcfg(struct i801_priv *priv)
pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hstcfg);
}
static void i801_restore_regs(struct i801_priv *priv)
{
outb_p(priv->original_hstcnt, SMBHSTCNT(priv));
pci_write_config_byte(priv->pci_dev, SMBHSTCFG, priv->original_hstcfg);
}
static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
int err, i;
@@ -1641,12 +1620,11 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
i2c_set_adapdata(&priv->adapter, priv);
priv->adapter.owner = THIS_MODULE;
priv->adapter.class = i801_get_adapter_class(priv);
priv->adapter.class = I2C_CLASS_HWMON;
priv->adapter.algo = &smbus_algorithm;
priv->adapter.dev.parent = &dev->dev;
ACPI_COMPANION_SET(&priv->adapter.dev, ACPI_COMPANION(&dev->dev));
acpi_use_parent_companion(&priv->adapter.dev);
priv->adapter.retries = 3;
mutex_init(&priv->acpi_lock);
priv->pci_dev = dev;
priv->features = id->driver_data;
@@ -1756,6 +1734,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
if (err) {
platform_device_unregister(priv->tco_pdev);
i801_acpi_remove(priv);
i801_restore_regs(priv);
return err;
}
@@ -1780,12 +1759,10 @@ static void i801_remove(struct pci_dev *dev)
{
struct i801_priv *priv = pci_get_drvdata(dev);
outb_p(priv->original_hstcnt, SMBHSTCNT(priv));
i801_disable_host_notify(priv);
i801_del_mux(priv);
i2c_del_adapter(&priv->adapter);
i801_acpi_remove(priv);
pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
platform_device_unregister(priv->tco_pdev);
@@ -1793,6 +1770,8 @@ static void i801_remove(struct pci_dev *dev)
if (!priv->acpi_reserved)
pm_runtime_get_noresume(&dev->dev);
i801_restore_regs(priv);
/*
* do not call pci_disable_device(dev) since it can cause hard hangs on
* some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010)
@@ -1803,18 +1782,18 @@ static void i801_shutdown(struct pci_dev *dev)
{
struct i801_priv *priv = pci_get_drvdata(dev);
/* Restore config registers to avoid hard hang on some systems */
outb_p(priv->original_hstcnt, SMBHSTCNT(priv));
i801_disable_host_notify(priv);
pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
/* Restore config registers to avoid hard hang on some systems */
i801_restore_regs(priv);
}
static int i801_suspend(struct device *dev)
{
struct i801_priv *priv = dev_get_drvdata(dev);
outb_p(priv->original_hstcnt, SMBHSTCNT(priv));
pci_write_config_byte(priv->pci_dev, SMBHSTCFG, priv->original_hstcfg);
i2c_mark_adapter_suspended(&priv->adapter);
i801_restore_regs(priv);
return 0;
}
@@ -1824,6 +1803,7 @@ static int i801_resume(struct device *dev)
i801_setup_hstcfg(priv);
i801_enable_host_notify(&priv->adapter);
i2c_mark_adapter_resumed(&priv->adapter);
return 0;
}
@@ -1842,16 +1822,11 @@ static struct pci_driver i801_driver = {
},
};
static int __init i2c_i801_init(void)
static int __init i2c_i801_init(struct pci_driver *drv)
{
if (dmi_name_in_vendors("FUJITSU"))
input_apanel_init();
return pci_register_driver(&i801_driver);
}
static void __exit i2c_i801_exit(void)
{
pci_unregister_driver(&i801_driver);
return pci_register_driver(drv);
}
MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
@@ -1859,5 +1834,4 @@ MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
MODULE_DESCRIPTION("I801 SMBus driver");
MODULE_LICENSE("GPL");
module_init(i2c_i801_init);
module_exit(i2c_i801_exit);
module_driver(i801_driver, i2c_i801_init, pci_unregister_driver);

View File

@@ -1442,15 +1442,19 @@ static int mtk_i2c_probe(struct platform_device *pdev)
if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk))
return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk);
i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = devm_clk_get_optional(&pdev->dev, "pmic");
if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk)) {
dev_err(&pdev->dev, "cannot get pmic clock\n");
return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk);
}
if (i2c->have_pmic) {
i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = devm_clk_get(&pdev->dev, "pmic");
if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk)) {
if (!i2c->clocks[I2C_MT65XX_CLK_PMIC].clk) {
dev_err(&pdev->dev, "cannot get pmic clock\n");
return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk);
return -ENODEV;
}
speed_clk = I2C_MT65XX_CLK_PMIC;
} else {
i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = NULL;
speed_clk = I2C_MT65XX_CLK_MAIN;
}

View File

@@ -19,11 +19,10 @@
#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/reset.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/delay.h>
@@ -859,7 +858,7 @@ static int
mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
struct device *dev)
{
const struct of_device_id *device;
const struct mv64xxx_i2c_regs *data;
struct device_node *np = dev->of_node;
u32 bus_freq, tclk;
int rc = 0;
@@ -897,11 +896,11 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
*/
drv_data->adapter.timeout = HZ;
device = of_match_device(mv64xxx_i2c_of_match_table, dev);
if (!device)
data = device_get_match_data(dev);
if (!data)
return -ENODEV;
memcpy(&drv_data->reg_offsets, device->data, sizeof(drv_data->reg_offsets));
memcpy(&drv_data->reg_offsets, data, sizeof(drv_data->reg_offsets));
/*
* For controllers embedded in new SoCs activate the

View File

@@ -25,11 +25,11 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/platform_data/i2c-omap.h>
#include <linux/pm_runtime.h>
#include <linux/pinctrl/consumer.h>
#include <linux/property.h>
/* I2C controller revisions */
#define OMAP_I2C_OMAP1_REV_2 0x20
@@ -1358,7 +1358,6 @@ omap_i2c_probe(struct platform_device *pdev)
const struct omap_i2c_bus_platform_data *pdata =
dev_get_platdata(&pdev->dev);
struct device_node *node = pdev->dev.of_node;
const struct of_device_id *match;
int irq;
int r;
u32 rev;
@@ -1376,11 +1375,10 @@ omap_i2c_probe(struct platform_device *pdev)
if (IS_ERR(omap->base))
return PTR_ERR(omap->base);
match = of_match_device(of_match_ptr(omap_i2c_of_match), &pdev->dev);
if (match) {
if (pdev->dev.of_node) {
u32 freq = I2C_MAX_STANDARD_MODE_FREQ;
pdata = match->data;
pdata = device_get_match_data(&pdev->dev);
omap->flags = pdata->flags;
of_property_read_u32(node, "clock-frequency", &freq);

View File

@@ -231,7 +231,7 @@ static void i2c_powermac_create_one(struct i2c_adapter *adap,
struct i2c_board_info info = {};
struct i2c_client *newdev;
strncpy(info.type, type, sizeof(info.type));
strscpy(info.type, type, sizeof(info.type));
info.addr = addr;
newdev = i2c_new_client_device(adap, &info);
if (IS_ERR(newdev))

View File

@@ -32,6 +32,7 @@
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/platform_data/i2c-pxa.h>
#include <linux/property.h>
#include <linux/slab.h>
/* I2C register field definitions */
@@ -1252,10 +1253,8 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,
enum pxa_i2c_types *i2c_types)
{
struct device_node *np = pdev->dev.of_node;
const struct of_device_id *of_id =
of_match_device(i2c_pxa_dt_ids, &pdev->dev);
if (!of_id)
if (!pdev->dev.of_node)
return 1;
/* For device tree we always use the dynamic or alias-assigned ID */
@@ -1264,7 +1263,7 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,
i2c->use_pio = of_property_read_bool(np, "mrvl,i2c-polling");
i2c->fast_mode = of_property_read_bool(np, "mrvl,i2c-fast-mode");
*i2c_types = (enum pxa_i2c_types)(of_id->data);
*i2c_types = (enum pxa_i2c_types)device_get_match_data(&pdev->dev);
return 0;
}

Some files were not shown because too many files have changed in this diff Show More