You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'i2c/for-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang:
- Peter Rosin did some major rework on the locking of i2c muxes by
seperating parent-locked muxes and mux-locked muxes.
This avoids deadlocks/workarounds when the mux itself needs i2c
commands for muxing. And as a side-effect, other workarounds in the
media layer could be eliminated. Also, Peter stepped up as the i2c
mux maintainer and will keep an eye on these changes.
- major updates to the octeon driver
- add a helper to the core to generate the address+rw_bit octal and
make drivers use it
- quite a bunch of driver updates
* 'i2c/for-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (84 commits)
i2c: rcar: add DMA support
i2c: st: Implement bus clear
i2c: only check scl functions when using generic recovery
i2c: algo-bit: declare i2c_bit_quirk_no_clk_stretch as static
i2c: tegra: disable clock before returning error
[media] rtl2832: regmap is aware of lockdep, drop local locking hack
[media] rtl2832_sdr: get rid of empty regmap wrappers
[media] rtl2832: change the i2c gate to be mux-locked
[media] si2168: change the i2c gate to be mux-locked
iio: imu: inv_mpu6050: change the i2c gate to be mux-locked
i2c: mux: document i2c muxes and elaborate on parent-/mux-locked muxes
i2c: mux: relax locking of the top i2c adapter during mux-locked muxing
i2c: muxes always lock the parent adapter
i2c: allow adapter drivers to override the adapter locking
i2c: uniphier: add "\n" at the end of error log
i2c: mv64xxx: remove CONFIG_HAVE_CLK conditionals
i2c: mv64xxx: use clk_{prepare_enable,disable_unprepare}
i2c: mv64xxx: handle probe deferral for the clock
i2c: mv64xxx: enable the driver on ARCH_MVEBU
i2c: octeon: Add workaround for broken irqs on CN3860
...
This commit is contained in:
@@ -4,6 +4,12 @@
|
||||
|
||||
Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
|
||||
|
||||
or
|
||||
|
||||
compatible: "cavium,octeon-7890-twsi"
|
||||
|
||||
Compatibility with cn78XX SOCs.
|
||||
|
||||
- reg: The base address of the TWSI/I2C bus controller register bank.
|
||||
|
||||
- #address-cells: Must be <1>.
|
||||
|
||||
@@ -19,6 +19,9 @@ Optional properties:
|
||||
- clock-frequency: desired I2C bus clock frequency in Hz. The absence of this
|
||||
property indicates the default frequency 100 kHz.
|
||||
- clocks: clock specifier.
|
||||
- dmas: Must contain a list of two references to DMA specifiers, one for
|
||||
transmission, and one for reception.
|
||||
- dma-names: Must contain a list of two DMA names, "tx" and "rx".
|
||||
|
||||
- i2c-scl-falling-time-ns: see i2c.txt
|
||||
- i2c-scl-internal-delay-ns: see i2c.txt
|
||||
|
||||
@@ -0,0 +1,370 @@
|
||||
I2C topology
|
||||
============
|
||||
|
||||
There are a couple of reasons for building more complex i2c topologies
|
||||
than a straight-forward i2c bus with one adapter and one or more devices.
|
||||
|
||||
1. A mux may be needed on the bus to prevent address collisions.
|
||||
|
||||
2. The bus may be accessible from some external bus master, and arbitration
|
||||
may be needed to determine if it is ok to access the bus.
|
||||
|
||||
3. A device (particularly RF tuners) may want to avoid the digital noise
|
||||
from the i2c bus, at least most of the time, and sits behind a gate
|
||||
that has to be operated before the device can be accessed.
|
||||
|
||||
Etc
|
||||
|
||||
These constructs are represented as i2c adapter trees by Linux, where
|
||||
each adapter has a parent adapter (except the root adapter) and zero or
|
||||
more child adapters. The root adapter is the actual adapter that issues
|
||||
i2c transfers, and all adapters with a parent are part of an "i2c-mux"
|
||||
object (quoted, since it can also be an arbitrator or a gate).
|
||||
|
||||
Depending of the particular mux driver, something happens when there is
|
||||
an i2c transfer on one of its child adapters. The mux driver can
|
||||
obviously operate a mux, but it can also do arbitration with an external
|
||||
bus master or open a gate. The mux driver has two operations for this,
|
||||
select and deselect. select is called before the transfer and (the
|
||||
optional) deselect is called after the transfer.
|
||||
|
||||
|
||||
Locking
|
||||
=======
|
||||
|
||||
There are two variants of locking available to i2c muxes, they can be
|
||||
mux-locked or parent-locked muxes. As is evident from below, it can be
|
||||
useful to know if a mux is mux-locked or if it is parent-locked. The
|
||||
following list was correct at the time of writing:
|
||||
|
||||
In drivers/i2c/muxes/
|
||||
i2c-arb-gpio-challenge Parent-locked
|
||||
i2c-mux-gpio Normally parent-locked, mux-locked iff
|
||||
all involved gpio pins are controlled by the
|
||||
same i2c root adapter that they mux.
|
||||
i2c-mux-pca9541 Parent-locked
|
||||
i2c-mux-pca954x Parent-locked
|
||||
i2c-mux-pinctrl Normally parent-locked, mux-locked iff
|
||||
all involved pinctrl devices are controlled
|
||||
by the same i2c root adapter that they mux.
|
||||
i2c-mux-reg Parent-locked
|
||||
|
||||
In drivers/iio/
|
||||
imu/inv_mpu6050/ Mux-locked
|
||||
|
||||
In drivers/media/
|
||||
dvb-frontends/m88ds3103 Parent-locked
|
||||
dvb-frontends/rtl2830 Parent-locked
|
||||
dvb-frontends/rtl2832 Mux-locked
|
||||
dvb-frontends/si2168 Mux-locked
|
||||
usb/cx231xx/ Parent-locked
|
||||
|
||||
|
||||
Mux-locked muxes
|
||||
----------------
|
||||
|
||||
Mux-locked muxes does not lock the entire parent adapter during the
|
||||
full select-transfer-deselect transaction, only the muxes on the parent
|
||||
adapter are locked. Mux-locked muxes are mostly interesting if the
|
||||
select and/or deselect operations must use i2c transfers to complete
|
||||
their tasks. Since the parent adapter is not fully locked during the
|
||||
full transaction, unrelated i2c transfers may interleave the different
|
||||
stages of the transaction. This has the benefit that the mux driver
|
||||
may be easier and cleaner to implement, but it has some caveats.
|
||||
|
||||
ML1. If you build a topology with a mux-locked mux being the parent
|
||||
of a parent-locked mux, this might break the expectation from the
|
||||
parent-locked mux that the root adapter is locked during the
|
||||
transaction.
|
||||
|
||||
ML2. It is not safe to build arbitrary topologies with two (or more)
|
||||
mux-locked muxes that are not siblings, when there are address
|
||||
collisions between the devices on the child adapters of these
|
||||
non-sibling muxes.
|
||||
|
||||
I.e. the select-transfer-deselect transaction targeting e.g. device
|
||||
address 0x42 behind mux-one may be interleaved with a similar
|
||||
operation targeting device address 0x42 behind mux-two. The
|
||||
intension with such a topology would in this hypothetical example
|
||||
be that mux-one and mux-two should not be selected simultaneously,
|
||||
but mux-locked muxes do not guarantee that in all topologies.
|
||||
|
||||
ML3. A mux-locked mux cannot be used by a driver for auto-closing
|
||||
gates/muxes, i.e. something that closes automatically after a given
|
||||
number (one, in most cases) of i2c transfers. Unrelated i2c transfers
|
||||
may creep in and close prematurely.
|
||||
|
||||
ML4. If any non-i2c operation in the mux driver changes the i2c mux state,
|
||||
the driver has to lock the root adapter during that operation.
|
||||
Otherwise garbage may appear on the bus as seen from devices
|
||||
behind the mux, when an unrelated i2c transfer is in flight during
|
||||
the non-i2c mux-changing operation.
|
||||
|
||||
|
||||
Mux-locked Example
|
||||
------------------
|
||||
|
||||
.----------. .--------.
|
||||
.--------. | mux- |-----| dev D1 |
|
||||
| root |--+--| locked | '--------'
|
||||
'--------' | | mux M1 |--. .--------.
|
||||
| '----------' '--| dev D2 |
|
||||
| .--------. '--------'
|
||||
'--| dev D3 |
|
||||
'--------'
|
||||
|
||||
When there is an access to D1, this happens:
|
||||
|
||||
1. Someone issues an i2c-transfer to D1.
|
||||
2. M1 locks muxes on its parent (the root adapter in this case).
|
||||
3. M1 calls ->select to ready the mux.
|
||||
4. M1 (presumably) does some i2c-transfers as part of its select.
|
||||
These transfers are normal i2c-transfers that locks the parent
|
||||
adapter.
|
||||
5. M1 feeds the i2c-transfer from step 1 to its parent adapter as a
|
||||
normal i2c-transfer that locks the parent adapter.
|
||||
6. M1 calls ->deselect, if it has one.
|
||||
7. Same rules as in step 4, but for ->deselect.
|
||||
8. M1 unlocks muxes on its parent.
|
||||
|
||||
This means that accesses to D2 are lockout out for the full duration
|
||||
of the entire operation. But accesses to D3 are possibly interleaved
|
||||
at any point.
|
||||
|
||||
|
||||
Parent-locked muxes
|
||||
-------------------
|
||||
|
||||
Parent-locked muxes lock the parent adapter during the full select-
|
||||
transfer-deselect transaction. The implication is that the mux driver
|
||||
has to ensure that any and all i2c transfers through that parent
|
||||
adapter during the transaction are unlocked i2c transfers (using e.g.
|
||||
__i2c_transfer), or a deadlock will follow. There are a couple of
|
||||
caveats.
|
||||
|
||||
PL1. If you build a topology with a parent-locked mux being the child
|
||||
of another mux, this might break a possible assumption from the
|
||||
child mux that the root adapter is unused between its select op
|
||||
and the actual transfer (e.g. if the child mux is auto-closing
|
||||
and the parent mux issus i2c-transfers as part of its select).
|
||||
This is especially the case if the parent mux is mux-locked, but
|
||||
it may also happen if the parent mux is parent-locked.
|
||||
|
||||
PL2. If select/deselect calls out to other subsystems such as gpio,
|
||||
pinctrl, regmap or iio, it is essential that any i2c transfers
|
||||
caused by these subsystems are unlocked. This can be convoluted to
|
||||
accomplish, maybe even impossible if an acceptably clean solution
|
||||
is sought.
|
||||
|
||||
|
||||
Parent-locked Example
|
||||
---------------------
|
||||
|
||||
.----------. .--------.
|
||||
.--------. | parent- |-----| dev D1 |
|
||||
| root |--+--| locked | '--------'
|
||||
'--------' | | mux M1 |--. .--------.
|
||||
| '----------' '--| dev D2 |
|
||||
| .--------. '--------'
|
||||
'--| dev D3 |
|
||||
'--------'
|
||||
|
||||
When there is an access to D1, this happens:
|
||||
|
||||
1. Someone issues an i2c-transfer to D1.
|
||||
2. M1 locks muxes on its parent (the root adapter in this case).
|
||||
3. M1 locks its parent adapter.
|
||||
4. M1 calls ->select to ready the mux.
|
||||
5. If M1 does any i2c-transfers (on this root adapter) as part of
|
||||
its select, those transfers must be unlocked i2c-transfers so
|
||||
that they do not deadlock the root adapter.
|
||||
6. M1 feeds the i2c-transfer from step 1 to the root adapter as an
|
||||
unlocked i2c-transfer, so that it does not deadlock the parent
|
||||
adapter.
|
||||
7. M1 calls ->deselect, if it has one.
|
||||
8. Same rules as in step 5, but for ->deselect.
|
||||
9. M1 unlocks its parent adapter.
|
||||
10. M1 unlocks muxes on its parent.
|
||||
|
||||
|
||||
This means that accesses to both D2 and D3 are locked out for the full
|
||||
duration of the entire operation.
|
||||
|
||||
|
||||
Complex Examples
|
||||
================
|
||||
|
||||
Parent-locked mux as parent of parent-locked mux
|
||||
------------------------------------------------
|
||||
|
||||
This is a useful topology, but it can be bad.
|
||||
|
||||
.----------. .----------. .--------.
|
||||
.--------. | parent- |-----| parent- |-----| dev D1 |
|
||||
| root |--+--| locked | | locked | '--------'
|
||||
'--------' | | mux M1 |--. | mux M2 |--. .--------.
|
||||
| '----------' | '----------' '--| dev D2 |
|
||||
| .--------. | .--------. '--------'
|
||||
'--| dev D4 | '--| dev D3 |
|
||||
'--------' '--------'
|
||||
|
||||
When any device is accessed, all other devices are locked out for
|
||||
the full duration of the operation (both muxes lock their parent,
|
||||
and specifically when M2 requests its parent to lock, M1 passes
|
||||
the buck to the root adapter).
|
||||
|
||||
This topology is bad if M2 is an auto-closing mux and M1->select
|
||||
issues any unlocked i2c transfers on the root adapter that may leak
|
||||
through and be seen by the M2 adapter, thus closing M2 prematurely.
|
||||
|
||||
|
||||
Mux-locked mux as parent of mux-locked mux
|
||||
------------------------------------------
|
||||
|
||||
This is a good topology.
|
||||
|
||||
.----------. .----------. .--------.
|
||||
.--------. | mux- |-----| mux- |-----| dev D1 |
|
||||
| root |--+--| locked | | locked | '--------'
|
||||
'--------' | | mux M1 |--. | mux M2 |--. .--------.
|
||||
| '----------' | '----------' '--| dev D2 |
|
||||
| .--------. | .--------. '--------'
|
||||
'--| dev D4 | '--| dev D3 |
|
||||
'--------' '--------'
|
||||
|
||||
When device D1 is accessed, accesses to D2 are locked out for the
|
||||
full duration of the operation (muxes on the top child adapter of M1
|
||||
are locked). But accesses to D3 and D4 are possibly interleaved at
|
||||
any point. Accesses to D3 locks out D1 and D2, but accesses to D4
|
||||
are still possibly interleaved.
|
||||
|
||||
|
||||
Mux-locked mux as parent of parent-locked mux
|
||||
---------------------------------------------
|
||||
|
||||
This is probably a bad topology.
|
||||
|
||||
.----------. .----------. .--------.
|
||||
.--------. | mux- |-----| parent- |-----| dev D1 |
|
||||
| root |--+--| locked | | locked | '--------'
|
||||
'--------' | | mux M1 |--. | mux M2 |--. .--------.
|
||||
| '----------' | '----------' '--| dev D2 |
|
||||
| .--------. | .--------. '--------'
|
||||
'--| dev D4 | '--| dev D3 |
|
||||
'--------' '--------'
|
||||
|
||||
When device D1 is accessed, accesses to D2 and D3 are locked out
|
||||
for the full duration of the operation (M1 locks child muxes on the
|
||||
root adapter). But accesses to D4 are possibly interleaved at any
|
||||
point.
|
||||
|
||||
This kind of topology is generally not suitable and should probably
|
||||
be avoided. The reason is that M2 probably assumes that there will
|
||||
be no i2c transfers during its calls to ->select and ->deselect, and
|
||||
if there are, any such transfers might appear on the slave side of M2
|
||||
as partial i2c transfers, i.e. garbage or worse. This might cause
|
||||
device lockups and/or other problems.
|
||||
|
||||
The topology is especially troublesome if M2 is an auto-closing
|
||||
mux. In that case, any interleaved accesses to D4 might close M2
|
||||
prematurely, as might any i2c-transfers part of M1->select.
|
||||
|
||||
But if M2 is not making the above stated assumption, and if M2 is not
|
||||
auto-closing, the topology is fine.
|
||||
|
||||
|
||||
Parent-locked mux as parent of mux-locked mux
|
||||
---------------------------------------------
|
||||
|
||||
This is a good topology.
|
||||
|
||||
.----------. .----------. .--------.
|
||||
.--------. | parent- |-----| mux- |-----| dev D1 |
|
||||
| root |--+--| locked | | locked | '--------'
|
||||
'--------' | | mux M1 |--. | mux M2 |--. .--------.
|
||||
| '----------' | '----------' '--| dev D2 |
|
||||
| .--------. | .--------. '--------'
|
||||
'--| dev D4 | '--| dev D3 |
|
||||
'--------' '--------'
|
||||
|
||||
When D1 is accessed, accesses to D2 are locked out for the full
|
||||
duration of the operation (muxes on the top child adapter of M1
|
||||
are locked). Accesses to D3 and D4 are possibly interleaved at
|
||||
any point, just as is expected for mux-locked muxes.
|
||||
|
||||
When D3 or D4 are accessed, everything else is locked out. For D3
|
||||
accesses, M1 locks the root adapter. For D4 accesses, the root
|
||||
adapter is locked directly.
|
||||
|
||||
|
||||
Two mux-locked sibling muxes
|
||||
----------------------------
|
||||
|
||||
This is a good topology.
|
||||
|
||||
.--------.
|
||||
.----------. .--| dev D1 |
|
||||
| mux- |--' '--------'
|
||||
.--| locked | .--------.
|
||||
| | mux M1 |-----| dev D2 |
|
||||
| '----------' '--------'
|
||||
| .----------. .--------.
|
||||
.--------. | | mux- |-----| dev D3 |
|
||||
| root |--+--| locked | '--------'
|
||||
'--------' | | mux M2 |--. .--------.
|
||||
| '----------' '--| dev D4 |
|
||||
| .--------. '--------'
|
||||
'--| dev D5 |
|
||||
'--------'
|
||||
|
||||
When D1 is accessed, accesses to D2, D3 and D4 are locked out. But
|
||||
accesses to D5 may be interleaved at any time.
|
||||
|
||||
|
||||
Two parent-locked sibling muxes
|
||||
-------------------------------
|
||||
|
||||
This is a good topology.
|
||||
|
||||
.--------.
|
||||
.----------. .--| dev D1 |
|
||||
| parent- |--' '--------'
|
||||
.--| locked | .--------.
|
||||
| | mux M1 |-----| dev D2 |
|
||||
| '----------' '--------'
|
||||
| .----------. .--------.
|
||||
.--------. | | parent- |-----| dev D3 |
|
||||
| root |--+--| locked | '--------'
|
||||
'--------' | | mux M2 |--. .--------.
|
||||
| '----------' '--| dev D4 |
|
||||
| .--------. '--------'
|
||||
'--| dev D5 |
|
||||
'--------'
|
||||
|
||||
When any device is accessed, accesses to all other devices are locked
|
||||
out.
|
||||
|
||||
|
||||
Mux-locked and parent-locked sibling muxes
|
||||
------------------------------------------
|
||||
|
||||
This is a good topology.
|
||||
|
||||
.--------.
|
||||
.----------. .--| dev D1 |
|
||||
| mux- |--' '--------'
|
||||
.--| locked | .--------.
|
||||
| | mux M1 |-----| dev D2 |
|
||||
| '----------' '--------'
|
||||
| .----------. .--------.
|
||||
.--------. | | parent- |-----| dev D3 |
|
||||
| root |--+--| locked | '--------'
|
||||
'--------' | | mux M2 |--. .--------.
|
||||
| '----------' '--| dev D4 |
|
||||
| .--------. '--------'
|
||||
'--| dev D5 |
|
||||
'--------'
|
||||
|
||||
When D1 or D2 are accessed, accesses to D3 and D4 are locked out while
|
||||
accesses to D5 may interleave. When D3 or D4 are accessed, accesses to
|
||||
all other devices are locked out.
|
||||
@@ -5348,6 +5348,7 @@ I2C MUXES
|
||||
M: Peter Rosin <peda@axentia.se>
|
||||
L: linux-i2c@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/i2c/i2c-topology
|
||||
F: Documentation/i2c/muxes/
|
||||
F: Documentation/devicetree/bindings/i2c/i2c-mux*
|
||||
F: drivers/i2c/i2c-mux.c
|
||||
|
||||
@@ -617,7 +617,7 @@ const struct i2c_algorithm i2c_bit_algo = {
|
||||
};
|
||||
EXPORT_SYMBOL(i2c_bit_algo);
|
||||
|
||||
const struct i2c_adapter_quirks i2c_bit_quirk_no_clk_stretch = {
|
||||
static const struct i2c_adapter_quirks i2c_bit_quirk_no_clk_stretch = {
|
||||
.flags = I2C_AQ_NO_CLK_STRETCH,
|
||||
};
|
||||
|
||||
|
||||
@@ -663,7 +663,7 @@ config I2C_MT65XX
|
||||
|
||||
config I2C_MV64XXX
|
||||
tristate "Marvell mv64xxx I2C Controller"
|
||||
depends on MV64X60 || PLAT_ORION || ARCH_SUNXI
|
||||
depends on MV64X60 || PLAT_ORION || ARCH_SUNXI || ARCH_MVEBU
|
||||
help
|
||||
If you say yes to this option, support will be included for the
|
||||
built-in I2C interface on the Marvell 64xxx line of host bridges.
|
||||
|
||||
@@ -267,7 +267,7 @@ static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c,
|
||||
iproc_i2c->msg = msg;
|
||||
|
||||
/* format and load slave address into the TX FIFO */
|
||||
addr = msg->addr << 1 | (msg->flags & I2C_M_RD ? 1 : 0);
|
||||
addr = i2c_8bit_addr_from_msg(msg);
|
||||
writel(addr, iproc_i2c->base + M_TX_OFFSET);
|
||||
|
||||
/*
|
||||
|
||||
@@ -501,10 +501,7 @@ static int bcm_kona_i2c_do_addr(struct bcm_kona_i2c_dev *dev,
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
} else {
|
||||
addr = msg->addr << 1;
|
||||
|
||||
if (msg->flags & I2C_M_RD)
|
||||
addr |= 1;
|
||||
addr = i2c_8bit_addr_from_msg(msg);
|
||||
|
||||
if (bcm_kona_i2c_write_byte(dev, addr, 0) < 0)
|
||||
return -EREMOTEIO;
|
||||
|
||||
@@ -446,9 +446,7 @@ static int brcmstb_i2c_do_addr(struct brcmstb_i2c_dev *dev,
|
||||
|
||||
}
|
||||
} else {
|
||||
addr = msg->addr << 1;
|
||||
if (msg->flags & I2C_M_RD)
|
||||
addr |= 1;
|
||||
addr = i2c_8bit_addr_from_msg(msg);
|
||||
|
||||
bsc_writel(dev, addr, chip_address);
|
||||
}
|
||||
|
||||
@@ -197,9 +197,7 @@ static void cpm_i2c_parse_message(struct i2c_adapter *adap,
|
||||
tbdf = cpm->tbase + tx;
|
||||
rbdf = cpm->rbase + rx;
|
||||
|
||||
addr = pmsg->addr << 1;
|
||||
if (pmsg->flags & I2C_M_RD)
|
||||
addr |= 1;
|
||||
addr = i2c_8bit_addr_from_msg(pmsg);
|
||||
|
||||
tb = cpm->txbuf[tx];
|
||||
rb = cpm->rxbuf[rx];
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mfd/dln2.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#define DLN2_I2C_MODULE_ID 0x03
|
||||
#define DLN2_I2C_CMD(cmd) DLN2_CMD(cmd, DLN2_I2C_MODULE_ID)
|
||||
@@ -210,6 +211,7 @@ static int dln2_i2c_probe(struct platform_device *pdev)
|
||||
dln2->adapter.algo = &dln2_i2c_usb_algorithm;
|
||||
dln2->adapter.quirks = &dln2_i2c_quirks;
|
||||
dln2->adapter.dev.parent = dev;
|
||||
ACPI_COMPANION_SET(&dln2->adapter.dev, ACPI_COMPANION(&pdev->dev));
|
||||
dln2->adapter.dev.of_node = dev->of_node;
|
||||
i2c_set_adapdata(&dln2->adapter, dln2);
|
||||
snprintf(dln2->adapter.name, sizeof(dln2->adapter.name), "%s-%s-%d",
|
||||
|
||||
@@ -861,14 +861,8 @@ static int exynos5_i2c_resume_noirq(struct device *dev)
|
||||
#endif
|
||||
|
||||
static const struct dev_pm_ops exynos5_i2c_dev_pm_ops = {
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.suspend_noirq = exynos5_i2c_suspend_noirq,
|
||||
.resume_noirq = exynos5_i2c_resume_noirq,
|
||||
.freeze_noirq = exynos5_i2c_suspend_noirq,
|
||||
.thaw_noirq = exynos5_i2c_resume_noirq,
|
||||
.poweroff_noirq = exynos5_i2c_suspend_noirq,
|
||||
.restore_noirq = exynos5_i2c_resume_noirq,
|
||||
#endif
|
||||
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(exynos5_i2c_suspend_noirq,
|
||||
exynos5_i2c_resume_noirq)
|
||||
};
|
||||
|
||||
static struct platform_driver exynos5_i2c_driver = {
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/platform_data/itco_wdt.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \
|
||||
defined CONFIG_DMI
|
||||
@@ -714,9 +715,11 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
|
||||
{
|
||||
int hwpec;
|
||||
int block = 0;
|
||||
int ret, xact = 0;
|
||||
int ret = 0, xact = 0;
|
||||
struct i801_priv *priv = i2c_get_adapdata(adap);
|
||||
|
||||
pm_runtime_get_sync(&priv->pci_dev->dev);
|
||||
|
||||
hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
|
||||
&& size != I2C_SMBUS_QUICK
|
||||
&& size != I2C_SMBUS_I2C_BLOCK_DATA;
|
||||
@@ -773,7 +776,8 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
|
||||
default:
|
||||
dev_err(&priv->pci_dev->dev, "Unsupported transaction %d\n",
|
||||
size);
|
||||
return -EOPNOTSUPP;
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hwpec) /* enable/disable hardware PEC */
|
||||
@@ -796,11 +800,11 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
|
||||
~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
|
||||
|
||||
if (block)
|
||||
return ret;
|
||||
goto out;
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out;
|
||||
if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
switch (xact & 0x7f) {
|
||||
case I801_BYTE: /* Result put in SMBHSTDAT0 */
|
||||
@@ -812,7 +816,11 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
|
||||
(inb_p(SMBHSTDAT1(priv)) << 8);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
||||
out:
|
||||
pm_runtime_mark_last_busy(&priv->pci_dev->dev);
|
||||
pm_runtime_put_autosuspend(&priv->pci_dev->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1413,6 +1421,11 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
|
||||
pci_set_drvdata(dev, priv);
|
||||
|
||||
pm_runtime_set_autosuspend_delay(&dev->dev, 1000);
|
||||
pm_runtime_use_autosuspend(&dev->dev);
|
||||
pm_runtime_put_autosuspend(&dev->dev);
|
||||
pm_runtime_allow(&dev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1420,6 +1433,9 @@ static void i801_remove(struct pci_dev *dev)
|
||||
{
|
||||
struct i801_priv *priv = pci_get_drvdata(dev);
|
||||
|
||||
pm_runtime_forbid(&dev->dev);
|
||||
pm_runtime_get_noresume(&dev->dev);
|
||||
|
||||
i801_del_mux(priv);
|
||||
i2c_del_adapter(&priv->adapter);
|
||||
pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
|
||||
@@ -1433,34 +1449,32 @@ static void i801_remove(struct pci_dev *dev)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int i801_suspend(struct pci_dev *dev, pm_message_t mesg)
|
||||
static int i801_suspend(struct device *dev)
|
||||
{
|
||||
struct i801_priv *priv = pci_get_drvdata(dev);
|
||||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||
struct i801_priv *priv = pci_get_drvdata(pci_dev);
|
||||
|
||||
pci_save_state(dev);
|
||||
pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
|
||||
pci_set_power_state(dev, pci_choose_state(dev, mesg));
|
||||
pci_write_config_byte(pci_dev, SMBHSTCFG, priv->original_hstcfg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i801_resume(struct pci_dev *dev)
|
||||
static int i801_resume(struct device *dev)
|
||||
{
|
||||
pci_set_power_state(dev, PCI_D0);
|
||||
pci_restore_state(dev);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define i801_suspend NULL
|
||||
#define i801_resume NULL
|
||||
#endif
|
||||
|
||||
static UNIVERSAL_DEV_PM_OPS(i801_pm_ops, i801_suspend,
|
||||
i801_resume, NULL);
|
||||
|
||||
static struct pci_driver i801_driver = {
|
||||
.name = "i801_smbus",
|
||||
.id_table = i801_ids,
|
||||
.probe = i801_probe,
|
||||
.remove = i801_remove,
|
||||
.suspend = i801_suspend,
|
||||
.resume = i801_resume,
|
||||
.driver = {
|
||||
.pm = &i801_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init i2c_i801_init(void)
|
||||
|
||||
@@ -269,7 +269,7 @@ static int iic_smbus_quick(struct ibm_iic_private* dev, const struct i2c_msg* p)
|
||||
ndelay(t->hd_sta);
|
||||
|
||||
/* Send address */
|
||||
v = (u8)((p->addr << 1) | ((p->flags & I2C_M_RD) ? 1 : 0));
|
||||
v = i2c_8bit_addr_from_msg(p);
|
||||
for (i = 0, mask = 0x80; i < 8; ++i, mask >>= 1){
|
||||
out_8(&iic->directcntl, sda);
|
||||
ndelay(t->low / 2);
|
||||
|
||||
@@ -751,9 +751,7 @@ static unsigned int img_i2c_atomic(struct img_i2c *i2c,
|
||||
switch (i2c->at_cur_cmd) {
|
||||
case CMD_GEN_START:
|
||||
next_cmd = CMD_GEN_DATA;
|
||||
next_data = (i2c->msg.addr << 1);
|
||||
if (i2c->msg.flags & I2C_M_RD)
|
||||
next_data |= 0x1;
|
||||
next_data = i2c_8bit_addr_from_msg(&i2c->msg);
|
||||
break;
|
||||
case CMD_GEN_DATA:
|
||||
if (i2c->line_status & LINESTAT_INPUT_HELD_V)
|
||||
|
||||
@@ -525,7 +525,7 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
|
||||
imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode, i2c_imx, IMX_I2C_I2CR);
|
||||
|
||||
/* Wait controller to be stable */
|
||||
udelay(50);
|
||||
usleep_range(50, 150);
|
||||
|
||||
/* Start I2C transaction */
|
||||
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
|
||||
|
||||
@@ -50,10 +50,7 @@ iic_cook_addr(struct i2c_msg *msg)
|
||||
{
|
||||
unsigned char addr;
|
||||
|
||||
addr = (msg->addr << 1);
|
||||
|
||||
if (msg->flags & I2C_M_RD)
|
||||
addr |= 1;
|
||||
addr = i2c_8bit_addr_from_msg(msg);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -133,9 +133,7 @@ static void i2c_lpc2k_pump_msg(struct lpc2k_i2c *i2c)
|
||||
case M_START:
|
||||
case M_REPSTART:
|
||||
/* Start bit was just sent out, send out addr and dir */
|
||||
data = i2c->msg->addr << 1;
|
||||
if (i2c->msg->flags & I2C_M_RD)
|
||||
data |= 1;
|
||||
data = i2c_8bit_addr_from_msg(i2c->msg);
|
||||
|
||||
writel(data, i2c->base + LPC24XX_I2DAT);
|
||||
writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONCLR);
|
||||
|
||||
@@ -413,10 +413,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
|
||||
else
|
||||
writew(I2C_FS_START_CON, i2c->base + OFFSET_EXT_CONF);
|
||||
|
||||
addr_reg = msgs->addr << 1;
|
||||
if (i2c->op == I2C_MASTER_RD)
|
||||
addr_reg |= 0x1;
|
||||
|
||||
addr_reg = i2c_8bit_addr_from_msg(msgs);
|
||||
writew(addr_reg, i2c->base + OFFSET_SLAVE_ADDR);
|
||||
|
||||
/* Clear interrupt status */
|
||||
|
||||
@@ -134,9 +134,7 @@ struct mv64xxx_i2c_data {
|
||||
int rc;
|
||||
u32 freq_m;
|
||||
u32 freq_n;
|
||||
#if defined(CONFIG_HAVE_CLK)
|
||||
struct clk *clk;
|
||||
#endif
|
||||
wait_queue_head_t waitq;
|
||||
spinlock_t lock;
|
||||
struct i2c_msg *msg;
|
||||
@@ -757,7 +755,6 @@ static const struct of_device_id mv64xxx_i2c_of_match_table[] = {
|
||||
MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
static int
|
||||
mv64xxx_calc_freq(struct mv64xxx_i2c_data *drv_data,
|
||||
const int tclk, const int n, const int m)
|
||||
@@ -791,25 +788,20 @@ mv64xxx_find_baud_factors(struct mv64xxx_i2c_data *drv_data,
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif /* CONFIG_HAVE_CLK */
|
||||
|
||||
static int
|
||||
mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
|
||||
struct device *dev)
|
||||
{
|
||||
/* CLK is mandatory when using DT to describe the i2c bus. We
|
||||
* need to know tclk in order to calculate bus clock
|
||||
* factors.
|
||||
*/
|
||||
#if !defined(CONFIG_HAVE_CLK)
|
||||
/* Have OF but no CLK */
|
||||
return -ENODEV;
|
||||
#else
|
||||
const struct of_device_id *device;
|
||||
struct device_node *np = dev->of_node;
|
||||
u32 bus_freq, tclk;
|
||||
int rc = 0;
|
||||
|
||||
/* CLK is mandatory when using DT to describe the i2c bus. We
|
||||
* need to know tclk in order to calculate bus clock
|
||||
* factors.
|
||||
*/
|
||||
if (IS_ERR(drv_data->clk)) {
|
||||
rc = -ENODEV;
|
||||
goto out;
|
||||
@@ -869,7 +861,6 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
|
||||
|
||||
out:
|
||||
return rc;
|
||||
#endif
|
||||
}
|
||||
#else /* CONFIG_OF */
|
||||
static int
|
||||
@@ -907,14 +898,13 @@ mv64xxx_i2c_probe(struct platform_device *pd)
|
||||
init_waitqueue_head(&drv_data->waitq);
|
||||
spin_lock_init(&drv_data->lock);
|
||||
|
||||
#if defined(CONFIG_HAVE_CLK)
|
||||
/* Not all platforms have a clk */
|
||||
drv_data->clk = devm_clk_get(&pd->dev, NULL);
|
||||
if (!IS_ERR(drv_data->clk)) {
|
||||
clk_prepare(drv_data->clk);
|
||||
clk_enable(drv_data->clk);
|
||||
}
|
||||
#endif
|
||||
if (IS_ERR(drv_data->clk) && PTR_ERR(drv_data->clk) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
if (!IS_ERR(drv_data->clk))
|
||||
clk_prepare_enable(drv_data->clk);
|
||||
|
||||
if (pdata) {
|
||||
drv_data->freq_m = pdata->freq_m;
|
||||
drv_data->freq_n = pdata->freq_n;
|
||||
@@ -964,13 +954,10 @@ exit_reset:
|
||||
if (!IS_ERR_OR_NULL(drv_data->rstc))
|
||||
reset_control_assert(drv_data->rstc);
|
||||
exit_clk:
|
||||
#if defined(CONFIG_HAVE_CLK)
|
||||
/* Not all platforms have a clk */
|
||||
if (!IS_ERR(drv_data->clk)) {
|
||||
clk_disable(drv_data->clk);
|
||||
clk_unprepare(drv_data->clk);
|
||||
}
|
||||
#endif
|
||||
if (!IS_ERR(drv_data->clk))
|
||||
clk_disable_unprepare(drv_data->clk);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -983,13 +970,9 @@ mv64xxx_i2c_remove(struct platform_device *dev)
|
||||
free_irq(drv_data->irq, drv_data);
|
||||
if (!IS_ERR_OR_NULL(drv_data->rstc))
|
||||
reset_control_assert(drv_data->rstc);
|
||||
#if defined(CONFIG_HAVE_CLK)
|
||||
/* Not all platforms have a clk */
|
||||
if (!IS_ERR(drv_data->clk)) {
|
||||
clk_disable(drv_data->clk);
|
||||
clk_unprepare(drv_data->clk);
|
||||
}
|
||||
#endif
|
||||
if (!IS_ERR(drv_data->clk))
|
||||
clk_disable_unprepare(drv_data->clk);
|
||||
|
||||
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