mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
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:
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
172
Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.yaml
Normal file
172
Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.yaml
Normal 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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user