linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v11 0/3] i2c: imx: add DMA support for freescale i2c driver
@ 2014-11-18 10:31 Yuan Yao
  2014-11-18 10:31 ` [PATCH v11 1/3] i2c: imx: Sort include headers alphabetically Yuan Yao
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Yuan Yao @ 2014-11-18 10:31 UTC (permalink / raw)
  To: wsa, marex
  Cc: LW, mark.rutland, fugang.duan, shawn.guo, linux-kernel,
	linux-arm-kernel, linux-i2c


Changed in v11: 
- Fix the bug for 'orig_jiffies' uninitialized.
- Use wait_for_completion_timeout() instead of wait_for_completion_interruptible_timeout(). 

Changed in v10: 
- Rebase to the latest code. 
- Add dma_submit_error for dmaengine_submit handling
- Some minor fixes for coding style. 

Changed in v9: 
- seperate a patch for sort include headers alphabetically 
- some minor fixes for coding style. 

Changed in v8: 
- some minor fixes for coding style. 
- unsetting I2CR_DMAEN immediatelly when DMA failed. 

Changed in v7: 
- when waiting for transfer complete use schedule() instead of udelay(). 

Changed in v6: 
- changed the inappropriate print message. 
- rebase to the latest code. 

Changed in v5: 
- add "*chan_dev = dma->chan_using->device->dev" for code cleanup. 
- add the test logs. 

Changed in v4: 
- cancelled "i2c_imx->use_dma". 
- changed "Dma" to "DMA". 
- add Timeout handling for Transfer complete. 

Changed in v3: 
- fix a bug when request the dma faild. 
- some minor fixes for coding style. 
- other minor fixes. 

Changed in v2: 
- remove has_dma_support property 
- unify i2c_imx_dma_rx and i2c_imx_dma_tx 
- unify i2c_imx_dma_read and i2c_imx_pio_read 
- unify i2c_imx_dma_write and i2c_imx_pio_write 

Added in v1: 
- Enable dma if it's support dma and transfer size bigger than the threshold. 
- Add device tree bindings for i2c eDMA support. 
- Add eDMA support for i2c driver. 


The test log of i2c DMA support: 

Starting kernel ... 

Booting Linux on physical CPU 0xf00 
Linux version 3.12.19-rt30+ (yuany@titan) (gcc version 4.8.3 20140401 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2014.04 - Linaro GCC 4.8-2014.04) ) #16 SMP Tue Nov 18 15:41:18 CST 2014 
CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=70c73c7d 
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache 
Machine: Freescale LS1021A, model: LS1021A TWR Board 
Memory policy: ECC disabled, Data cache writealloc 
PERCPU: Embedded 8 pages/cpu @80d46000 s8896 r8192 d15680 u32768 
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 260096 
Kernel command line: root=/dev/ram rw console=ttyS0,115200 ramdisk_size=500000 no_console_suspend 
PID hash table entries: 4096 (order: 2, 16384 bytes) 
Dentry cache hash table entries: 131072 (order: 7, 524288 bytes) 
Inode-cache hash table entries: 65536 (order: 6, 262144 bytes) 
Memory: 1015380K/1048576K available (3184K kernel code, 265K rwdata, 1472K rodata, 156K init, 211K bss, 33196K reserved, 0K highmem) 
Virtual kernel memory layout: 
vector : 0xffff0000 - 0xffff1000 ( 4 kB) 
fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB) 
vmalloc : 0xc0800000 - 0xff000000 (1000 MB) 
lowmem : 0x80000000 - 0xc0000000 (1024 MB) 
pkmap : 0x7fe00000 - 0x80000000 ( 2 MB) 
modules : 0x7f800000 - 0x7fe00000 ( 6 MB) 
.text : 0x80008000 - 0x80494374 (4657 kB) 
.init : 0x80495000 - 0x804bc2c0 ( 157 kB) 
.data : 0x804be000 - 0x805005a0 ( 266 kB) 
.bss : 0x805005a8 - 0x80535450 ( 212 kB) 
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1 
Hierarchical RCU implementation. 
RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2. 
NR_IRQS:16 nr_irqs:16 16 
Architected cp15 timer(s) running at 12.50MHz (phys). 
Switching to timer-based delay loop 
sched_clock: ARM arch timer >56 bits at 12500kHz, resolution 80ns 
sched_clock: 32 bits at 100 Hz, resolution 10000000ns, wraps every 4294967286ms 
Console: colour dummy device 80x30 
Calibrating delay loop (skipped), value calculated using timer frequency.. 25.00 BogoMIPS (lpj=125000) 
pid_max: default: 32768 minimum: 301 
Mount-cache hash table entries: 512 
CPU: Testing write buffer coherency: ok 
CPU0: update cpu_power 1024 
CPU0: thread -1, cpu 0, socket 15, mpidr 80000f00 
Setting up static identity map for 0x802f9e20 - 0x802f9e84 
CPU1: Booted secondary processor 
CPU1: update cpu_power 1024 
CPU1: thread -1, cpu 1, socket 15, mpidr 80000f01 
Brought up 2 CPUs 
SMP: Total of 2 processors activated. 
CPU: All CPU(s) started in HYP mode. 
CPU: Virtualization extensions available. 
devtmpfs: initialized 
VFP support v0.3: implementor 41 architecture 2 part 30 variant 7 rev 5 
regulator-dummy: no parameters 
NET: Registered protocol family 16 
DMA: preallocated 256 KiB pool for atomic coherent allocations 
cpuidle: using governor ladder 
cpuidle: using governor menu 
syscon 1570000.scfg: regmap [mem 0x01570000-0x0157ffff] registered 
irq: no irq domain found for /soc/uqe@2400000/qeic@80 ! 
irq: no irq domain found for /soc/uqe@2400000/qeic@80 ! 
hw-breakpoint: found 5 (+1 reserved) breakpoint and 4 watchpoint registers. 
hw-breakpoint: maximum watchpoint size is 8 bytes. 
bio: create slab <bio-0> at 0 
3P3V: 3300 mV 
vgaarb: loaded 
SCSI subsystem initialized 
usbcore: registered new interface driver usbfs 
usbcore: registered new interface driver hub 
usbcore: registered new device driver usb 
i2c i2c-0: IMX I2C adapter registered 
i2c i2c-0: using dma0chan16 (tx) and dma0chan17 (rx) for DMA transfers 
i2c i2c-1: IMX I2C adapter registered 
i2c i2c-1: using dma0chan18 (tx) and dma0chan19 (rx) for DMA transfers 
i2c i2c-2: of_i2c: modalias failure on /soc/i2c@21a0000/ltc2945@67 
i2c i2c-2: IMX I2C adapter registered 
of_dma_request_slave_channel: dma-names property of node '/soc/i2c@21a0000' missing or empty 
i2c i2c-2: can't use DMA 
pps_core: LinuxPPS API ver. 1 registered 
pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> 
PTP clock support registered 
fsl-ifc 1530000.ifc: Freescale Integrated Flash Controller 
Advanced Linux Sound Architecture Driver Initialized. 
Switched to clocksource arch_sys_counter 
NET: Registered protocol family 2 
TCP established hash table entries: 8192 (order: 4, 65536 bytes) 
TCP bind hash table entries: 8192 (order: 5, 163840 bytes) 
TCP: Hash tables configured (established 8192 bind 8192) 
TCP: reno registered 
UDP hash table entries: 512 (order: 2, 24576 bytes) 
UDP-Lite hash table entries: 512 (order: 2, 24576 bytes) 
NET: Registered protocol family 1 
RPC: Registered named UNIX socket transport module. 
RPC: Registered udp transport module. 
RPC: Registered tcp transport module. 
RPC: Registered tcp NFSv4.1 backchannel transport module. 
Trying to unpack rootfs image as initramfs... 
rootfs image is not initramfs (no cpio magic); looks like an initrd 
Freeing initrd memory: 18704K (bdcec000 - bef30000) 
hw perfevents: enabled with ARMv7 Cortex-A7 PMU driver, 5 counters available 
NFS: Registering the id_resolver key type 
Key type id_resolver registered 
Key type id_legacy registered 
jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc. 
msgmni has been set to 2019 
io scheduler noop registered 
io scheduler deadline registered 
io scheduler cfq registered (default) 
layerscape-pcie 3400000.pcie: phy link never came up 
layerscape-pcie 3400000.pcie: PCI host bridge to bus 0000:00 
pci_bus 0000:00: root bus resource [io 0x1000-0xffff] 
pci_bus 0000:00: root bus resource [mem 0x4040000000-0x407fffffff] (bus address [0x40000000-0x7fffffff]) 
pci_bus 0000:00: root bus resource [bus 00-ff] 
PCI: bus0: Fast back to back transfers disabled 
PCI: bus1: Fast back to back transfers enabled 
pci 0000:00:00.0: BAR 1: assigned [mem 0x4040000000-0x4043ffffff] 
pci 0000:00:00.0: BAR 0: assigned [mem 0x4044000000-0x4044ffffff] 
pci 0000:00:00.0: BAR 6: assigned [mem 0x4045000000-0x4045ffffff pref] 
pci 0000:00:00.0: PCI bridge to [bus 01] 
layerscape-pcie 3500000.pcie: phy link never came up 
layerscape-pcie 3500000.pcie: PCI host bridge to bus 0001:00 
pci_bus 0001:00: root bus resource [io 0x10000-0x1ffff] (bus address [0x0000-0xffff]) 
pci_bus 0001:00: root bus resource [mem 0x4840000000-0x487fffffff] (bus address [0x40000000-0x7fffffff]) 
pci_bus 0001:00: root bus resource [bus 00-ff] 
PCI: bus0: Fast back to back transfers disabled 
PCI: bus1: Fast back to back transfers enabled 
pci 0001:00:00.0: BAR 1: assigned [mem 0x4840000000-0x4843ffffff] 
pci 0001:00:00.0: BAR 0: assigned [mem 0x4844000000-0x4844ffffff] 
pci 0001:00:00.0: BAR 6: assigned [mem 0x4845000000-0x4845ffffff pref] 
pci 0001:00:00.0: PCI bridge to [bus 01] 
sii902x: probe of 1-0039 failed with error -1 
Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled 
21c0500.serial: ttyS0 at MMIO 0x21c0500 (irq = 118, base_baud = 9375000) is a 16550A_FSL64 
console [ttyS0] enabled 
21c0600.serial: ttyS1 at MMIO 0x21c0600 (irq = 118, base_baud = 9375000) is a 16550A_FSL64 
of_serial 2402200.ucc: clk or clock-frequency not defined 
of_serial: probe of 2402200.ucc failed with error -2 
serial: Freescale lpuart driver 
2950000.serial: ttyLP0 at MMIO 0x2950000 (irq = 112, base_baud = 6250000) is a FSL_LPUART 
brd: module loaded 
loop: module loaded 
60000000.nor: Found 1 x16 devices at 0x0 in 16-bit bank. Manufacturer ID 0x000089 Chip ID 0x00227e 
Amd/Fujitsu Extended Query Table at 0x0040 
Amd/Fujitsu Extended Query version 1.3. 
number of CFI chips: 1 
8 ofpart partitions found on MTD device 60000000.nor 
Creating 8 MTD partitions on "60000000.nor": 
0x000000000000-0x000000020000 : "NOR bank0 RCW Image" 
0x000000020000-0x000000120000 : "NOR DTB Image" 
0x000000120000-0x000000920000 : "NOR Linux Kernel Image" 
0x000000920000-0x000003f20000 : "NOR Ramdisk Root File System Image" 
0x000003f80000-0x000004000000 : "NOR bank4 u-boot Image" 
0x000004000000-0x000004020000 : "NOR bank4 RCW Image" 
0x000004020000-0x000007f20000 : "NOR JFFS2 ROOT File System Image" 
0x000007f80000-0x000008000000 : "NOR bank0 u-boot Image" 
fsl-quadspi 1550000.quadspi: found mr25h256, expected n25q128a13 
fsl-quadspi 1550000.quadspi: mr25h256 (32 Kbytes) 
fsl-quadspi 1550000.quadspi: Unsupported cmd 0x03 
fsl-quadspi 1550000.quadspi: QuadSPI SPI NOR flash driver 
fsl-dspi 2110000.dspi: can't get dspi transfer mode 
CAN device driver interface 
libphy: Freescale PowerQUICC MII Bus: probed 
fsl-gianfar ethernet.4: enabled errata workarounds, flags: 0x4 
fsl-gianfar ethernet.4 eth0: mac: 00:04:9f:03:5c:33 
fsl-gianfar ethernet.4 eth0: Running with NAPI enabled 
fsl-gianfar ethernet.4 eth0: RX BD ring size for Q[0]: 256 
fsl-gianfar ethernet.4 eth0: TX BD ring size for Q[0]: 256 
fsl-gianfar ethernet.5: enabled errata workarounds, flags: 0x4 
fsl-gianfar ethernet.5 eth1: mac: 00:04:9f:03:5c:34 
fsl-gianfar ethernet.5 eth1: Running with NAPI enabled 
fsl-gianfar ethernet.5 eth1: RX BD ring size for Q[0]: 256 
fsl-gianfar ethernet.5 eth1: TX BD ring size for Q[0]: 256 
fsl-gianfar ethernet.6: enabled errata workarounds, flags: 0x4 
fsl-gianfar ethernet.6 eth2: mac: 00:04:9f:03:5c:34 
fsl-gianfar ethernet.6 eth2: Running with NAPI enabled 
fsl-gianfar ethernet.6 eth2: RX BD ring size for Q[0]: 256 
fsl-gianfar ethernet.6 eth2: TX BD ring size for Q[0]: 256 
e1000e: Intel(R) PRO/1000 Network Driver - 2.3.2-k 
e1000e: Copyright(c) 1999 - 2013 Intel Corporation. 
usbcore: registered new interface driver usb-storage 
mousedev: PS/2 mouse device common for all mice 
i2c /dev entries driver 
imx2-wdt 2ad0000.wdog: timeout 60 sec (nowayout=0) 
qoriq_cpufreq: Freescale PowerPC qoriq CPU frequency scaling driver 
sdhci: Secure Digital Host Controller Interface driver 
sdhci: Copyright(c) Pierre Ossman 
sdhci-pltfm: SDHCI platform and OF driver helper 
mmc0: no vqmmc regulator found 
mmc0: no vmmc regulator found 
mmc0: SDHCI controller on 1560000.esdhc [1560000.esdhc] using ADMA 
caam 1700000.crypto: Instantiated RNG4 SH0 
caam 1700000.crypto: Instantiated RNG4 SH1 
caam 1700000.crypto: device ID = 0x0a14030000000000 (Era 67108864) 
caam 1700000.crypto: job rings = 4, qi = 0 
caam algorithms registered in /proc/crypto 
caam_jr 1710000.jr: registering rng-caam 
caam 1700000.crypto: fsl,sec-v5.3 algorithms registered in /proc/crypto 
usbcore: registered new interface driver usbhid 
usbhid: USB HID core driver 
sgtl5000 1-000a: sgtl5000 revision 0x11 
sgtl5000 1-000a: Failed to get supply 'VDDD': -19 
1-000a: 1200 mV normal 
sgtl5000 1-000a: Using internal LDO instead of VDDD 
vf610-sgtl5000 sound.9: sgtl5000 <-> 2b50000.sai mapping ok 
oprofile: using timer interrupt. 
TCP: cubic registered 
Initializing XFRM netlink socket 
NET: Registered protocol family 17 
NET: Registered protocol family 15 
can: controller area network core (rev 20120528 abi 9) 
NET: Registered protocol family 29 
can: raw protocol (rev 20120528) 
Key type dns_resolver registered 
regulator-dummy: disabling 
drivers/rtc/hctosys.c: unable to open rtc device (rtc0) 
ALSA device list: 
#0: FSL-VF610-TWR-BOARD 
RAMDISK: gzip image found at block 0 
VFS: Mounted root (ext2 filesystem) on device 1:0. 
devtmpfs: mounted 
Freeing unused kernel memory: 156K (80495000 - 804bc000) 
INIT: version 2.88 booting 
Starting udev 
udevd[123]: starting version 182 
Starting Bootlog daemon: bootlogd. 
Populating dev cache 
Configuring network interfaces... udhcpc (v1.21.1) started 
Sending discover... 
libphy: mdio@2d24000:02 - Link is Down 
Sending discover... 
libphy: mdio@2d24000:02 - Link is Up - 1000/Full 
Sending discover... 
No lease, failing 
net.ipv4.conf.default.rp_filter = 1 
net.ipv4.conf.all.rp_filter = 1 
hwclock: can't open '/dev/misc/rtc': No such file or directory 
Wed Jun 25 11:59:00 UTC 2014 
hwclock: can't open '/dev/misc/rtc': No such file or directory 
Running postinst /etc/rpm-postinsts/100-sysvinit-inittab... 
Running postinst /etc/rpm-postinsts/101-debianutils... 
update-rc.d: /etc/init.d/run-postinsts exists during rc.d purge (continuing) 
Removing any system startup links for run-postinsts ... 
/etc/rcS.d/S99run-postinsts 
INIT: Entering runlevel: 5 
Starting OpenBSD Secure Shell server: sshd 
generating ssh RSA key... 
generating ssh ECDSA key... 
generating ssh DSA key... 
done. 
hwclock: can't open '/dev/misc/rtc': No such file or directory 
Starting network benchmark server: netserver. 
Starting system log daemon...0 
Starting kernel log daemon...0 
Starting internet superserver: xinetd. 
Stopping Bootlog daemon: bootlogd. 

Poky (Yocto Project Reference Distro) 1.5 ls1021atwr /dev/ttyS0

ls1021atwr login: root 
root@ls1021atwr:~# i2cdump -y 1 0x52 i 
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 
00: 55 55 55 55 aa aa aa aa ff ff ff ff ff ff ff ff UUUU????........ 
10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
30: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
root@ls1021atwr:~# i2cdump -y 1 0x52 
No size specified (using byte-data access) 
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 
00: 55 55 55 55 aa aa aa aa ff ff ff ff ff ff ff ff UUUU????........ 
10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
30: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
root@ls1021atwr:~# i2cset -f -y 1 0x52 0x00 0xa0 0xa1 0xa2 0xa3 0xa4 0xa5 0xa6 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xaf i 
root@ls1021atwr:~# i2cset -f -y 1 0x52 0x10 0xb0 0xb1 0xb2 0xb3 0xb4 0xb5 0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf i 
root@ls1021atwr:~# i2cset -f -y 1 0x52 0x20 0xc0 0xc1 0xc2 0xc3 0xc4 0xc5 0xc6 0xc7 0xc8 0xc9 0xca 0xcb 0xcc 0xcd 0xce 0xcf i 
root@ls1021atwr:~# i2cset -f -y 1 0x52 0x30 0xd0 0xd1 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9 0xda 0xdb 0xdc 0xdd 0xde 0xdf i 
root@ls1021atwr:~# i2cset -f -y 1 0x52 0x40 0xe0 0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe8 0xe9 0xea 0xeb 0xec 0xed 0xee 0xef i 
root@ls1021atwr:~# i2cdump -y 1 0x52 i 
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 
00: a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af ???????????????? 
10: b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf ???????????????? 
20: c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf ???????????????? 
30: d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df ???????????????? 
40: e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef ???????????????? 
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
root@ls1021atwr:~# i2cdump -y 1 0x52 
No size specified (using byte-data access) 
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 
00: a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af ???????????????? 
10: b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf ???????????????? 
20: c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf ???????????????? 
30: d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df ???????????????? 
40: e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef ???????????????? 
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v11 1/3] i2c: imx: Sort include headers alphabetically
  2014-11-18 10:31 [PATCH v11 0/3] i2c: imx: add DMA support for freescale i2c driver Yuan Yao
@ 2014-11-18 10:31 ` Yuan Yao
  2014-11-18 10:31 ` [PATCH v11 2/3] Documentation:add DMA support for freescale i2c driver Yuan Yao
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Yuan Yao @ 2014-11-18 10:31 UTC (permalink / raw)
  To: wsa, marex
  Cc: LW, mark.rutland, fugang.duan, shawn.guo, linux-kernel,
	linux-arm-kernel, linux-i2c

If the inlcude headers aren't sorted alphabetically, then the
logical choice is to append new ones, however that creates a
lot of potential for conflicts or duplicates because every change
will then add new includes in the same location.

Signed-off-by: Yuan Yao <yao.yuan@freescale.com>
---
 drivers/i2c/busses/i2c-imx.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index a7a2a79..d025c47 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -32,22 +32,22 @@
 /** Includes *******************************************************************
 *******************************************************************************/
 
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
+#include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/errno.h>
 #include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
-#include <linux/sched.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/platform_data/i2c-imx.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
 
 /** Defines ********************************************************************
 *******************************************************************************/
-- 
2.1.0.27.g96db324


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v11 2/3] Documentation:add DMA support for freescale i2c driver
  2014-11-18 10:31 [PATCH v11 0/3] i2c: imx: add DMA support for freescale i2c driver Yuan Yao
  2014-11-18 10:31 ` [PATCH v11 1/3] i2c: imx: Sort include headers alphabetically Yuan Yao
@ 2014-11-18 10:31 ` Yuan Yao
  2014-11-18 10:31 ` [PATCH v11 3/3] i2c: imx: add " Yuan Yao
  2014-11-18 15:01 ` [PATCH v11 0/3] " Wolfram Sang
  3 siblings, 0 replies; 5+ messages in thread
From: Yuan Yao @ 2014-11-18 10:31 UTC (permalink / raw)
  To: wsa, marex
  Cc: LW, mark.rutland, fugang.duan, shawn.guo, linux-kernel,
	linux-arm-kernel, linux-i2c

Add i2c dts node properties for eDMA support, them depend on the eDMA driver.

Signed-off-by: Yuan Yao <yao.yuan@freescale.com>
---
 Documentation/devicetree/bindings/i2c/i2c-imx.txt | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx.txt b/Documentation/devicetree/bindings/i2c/i2c-imx.txt
index 4a8513e..52d37fd 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-imx.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-imx.txt
@@ -11,6 +11,8 @@ Required properties:
 Optional properties:
 - clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz.
   The absence of the propoerty indicates the default frequency 100 kHz.
+- dmas: A list of two dma specifiers, one for each entry in dma-names.
+- dma-names: should contain "tx" and "rx".
 
 Examples:
 
@@ -26,3 +28,12 @@ i2c@70038000 { /* HS-I2C on i.MX51 */
 	interrupts = <64>;
 	clock-frequency = <400000>;
 };
+
+i2c0: i2c@40066000 { /* i2c0 on vf610 */
+	compatible = "fsl,vf610-i2c";
+	reg = <0x40066000 0x1000>;
+	interrupts =<0 71 0x04>;
+	dmas = <&edma0 0 50>,
+		<&edma0 0 51>;
+	dma-names = "rx","tx";
+};
-- 
2.1.0.27.g96db324


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v11 3/3] i2c: imx: add DMA support for freescale i2c driver
  2014-11-18 10:31 [PATCH v11 0/3] i2c: imx: add DMA support for freescale i2c driver Yuan Yao
  2014-11-18 10:31 ` [PATCH v11 1/3] i2c: imx: Sort include headers alphabetically Yuan Yao
  2014-11-18 10:31 ` [PATCH v11 2/3] Documentation:add DMA support for freescale i2c driver Yuan Yao
@ 2014-11-18 10:31 ` Yuan Yao
  2014-11-18 15:01 ` [PATCH v11 0/3] " Wolfram Sang
  3 siblings, 0 replies; 5+ messages in thread
From: Yuan Yao @ 2014-11-18 10:31 UTC (permalink / raw)
  To: wsa, marex
  Cc: LW, mark.rutland, fugang.duan, shawn.guo, linux-kernel,
	linux-arm-kernel, linux-i2c

Add dma support for i2c. This function depend on DMA driver.
You can turn on it by write both the dmas and dma-name properties in dts node.
DMA is optional, even DMA request unsuccessfully, i2c can also work well.

Signed-off-by: Yuan Yao <yao.yuan@freescale.com>
---
 drivers/i2c/busses/i2c-imx.c | 335 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 333 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index d025c47..634ee62 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -33,7 +33,11 @@
 *******************************************************************************/
 
 #include <linux/clk.h>
+#include <linux/completion.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/dmapool.h>
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/i2c.h>
@@ -44,6 +48,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_dma.h>
 #include <linux/platform_data/i2c-imx.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
@@ -58,6 +63,15 @@
 /* Default value */
 #define IMX_I2C_BIT_RATE	100000	/* 100kHz */
 
+/*
+ * Enable DMA if transfer byte size is bigger than this threshold.
+ * As the hardware request, it must bigger than 4 bytes.\
+ * I have set '16' here, maybe it's not the best but I think it's
+ * the appropriate.
+ */
+#define DMA_THRESHOLD	16
+#define DMA_TIMEOUT	1000
+
 /* IMX I2C registers:
  * the I2C register offset is different between SoCs,
  * to provid support for all these chips, split the
@@ -83,6 +97,7 @@
 #define I2SR_IBB	0x20
 #define I2SR_IAAS	0x40
 #define I2SR_ICF	0x80
+#define I2CR_DMAEN	0x02
 #define I2CR_RSTA	0x04
 #define I2CR_TXAK	0x08
 #define I2CR_MTX	0x10
@@ -169,6 +184,17 @@ struct imx_i2c_hwdata {
 	unsigned		i2cr_ien_opcode;
 };
 
+struct imx_i2c_dma {
+	struct dma_chan		*chan_tx;
+	struct dma_chan		*chan_rx;
+	struct dma_chan		*chan_using;
+	struct completion	cmd_complete;
+	dma_addr_t		dma_buf;
+	unsigned int		dma_len;
+	enum dma_transfer_direction dma_transfer_dir;
+	enum dma_data_direction dma_data_dir;
+};
+
 struct imx_i2c_struct {
 	struct i2c_adapter	adapter;
 	struct clk		*clk;
@@ -181,6 +207,8 @@ struct imx_i2c_struct {
 	unsigned int		cur_clk;
 	unsigned int		bitrate;
 	const struct imx_i2c_hwdata	*hwdata;
+
+	struct imx_i2c_dma	*dma;
 };
 
 static const struct imx_i2c_hwdata imx1_i2c_hwdata  = {
@@ -251,6 +279,138 @@ static inline unsigned char imx_i2c_read_reg(struct imx_i2c_struct *i2c_imx,
 	return readb(i2c_imx->base + (reg << i2c_imx->hwdata->regshift));
 }
 
+/* Functions for DMA support */
+static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx,
+						dma_addr_t phy_addr)
+{
+	struct imx_i2c_dma *dma;
+	struct dma_slave_config dma_sconfig;
+	struct device *dev = &i2c_imx->adapter.dev;
+	int ret;
+
+	dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
+	if (!dma)
+		return;
+
+	dma->chan_tx = dma_request_slave_channel(dev, "tx");
+	if (!dma->chan_tx) {
+		dev_dbg(dev, "can't request DMA tx channel\n");
+		ret = -ENODEV;
+		goto fail_al;
+	}
+
+	dma_sconfig.dst_addr = phy_addr +
+				(IMX_I2C_I2DR << i2c_imx->hwdata->regshift);
+	dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	dma_sconfig.dst_maxburst = 1;
+	dma_sconfig.direction = DMA_MEM_TO_DEV;
+	ret = dmaengine_slave_config(dma->chan_tx, &dma_sconfig);
+	if (ret < 0) {
+		dev_dbg(dev, "can't configure tx channel\n");
+		goto fail_tx;
+	}
+
+	dma->chan_rx = dma_request_slave_channel(dev, "rx");
+	if (!dma->chan_rx) {
+		dev_dbg(dev, "can't request DMA rx channel\n");
+		ret = -ENODEV;
+		goto fail_tx;
+	}
+
+	dma_sconfig.src_addr = phy_addr +
+				(IMX_I2C_I2DR << i2c_imx->hwdata->regshift);
+	dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	dma_sconfig.src_maxburst = 1;
+	dma_sconfig.direction = DMA_DEV_TO_MEM;
+	ret = dmaengine_slave_config(dma->chan_rx, &dma_sconfig);
+	if (ret < 0) {
+		dev_dbg(dev, "can't configure rx channel\n");
+		goto fail_rx;
+	}
+
+	i2c_imx->dma = dma;
+	init_completion(&dma->cmd_complete);
+	dev_info(dev, "using %s (tx) and %s (rx) for DMA transfers\n",
+		dma_chan_name(dma->chan_tx), dma_chan_name(dma->chan_rx));
+
+	return;
+
+fail_rx:
+	dma_release_channel(dma->chan_rx);
+fail_tx:
+	dma_release_channel(dma->chan_tx);
+fail_al:
+	devm_kfree(dev, dma);
+	dev_info(dev, "can't use DMA\n");
+}
+
+static void i2c_imx_dma_callback(void *arg)
+{
+	struct imx_i2c_struct *i2c_imx = (struct imx_i2c_struct *)arg;
+	struct imx_i2c_dma *dma = i2c_imx->dma;
+
+	dma_unmap_single(dma->chan_using->device->dev, dma->dma_buf,
+			dma->dma_len, dma->dma_data_dir);
+	complete(&dma->cmd_complete);
+}
+
+static int i2c_imx_dma_xfer(struct imx_i2c_struct *i2c_imx,
+					struct i2c_msg *msgs)
+{
+	struct imx_i2c_dma *dma = i2c_imx->dma;
+	struct dma_async_tx_descriptor *txdesc;
+	struct device *dev = &i2c_imx->adapter.dev;
+	struct device *chan_dev = dma->chan_using->device->dev;
+
+	dma->dma_buf = dma_map_single(chan_dev, msgs->buf,
+					dma->dma_len, dma->dma_data_dir);
+	if (dma_mapping_error(chan_dev, dma->dma_buf)) {
+		dev_err(dev, "DMA mapping failed\n");
+		goto err_map;
+	}
+
+	txdesc = dmaengine_prep_slave_single(dma->chan_using, dma->dma_buf,
+					dma->dma_len, dma->dma_transfer_dir,
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!txdesc) {
+		dev_err(dev, "Not able to get desc for DMA xfer\n");
+		goto err_desc;
+	}
+
+	txdesc->callback = i2c_imx_dma_callback;
+	txdesc->callback_param = i2c_imx;
+	if (dma_submit_error(dmaengine_submit(txdesc))) {
+		dev_err(dev, "DMA submit failed\n");
+		goto err_submit;
+	}
+
+	dma_async_issue_pending(dma->chan_using);
+	return 0;
+
+err_submit:
+err_desc:
+	dma_unmap_single(chan_dev, dma->dma_buf,
+			dma->dma_len, dma->dma_data_dir);
+err_map:
+	return -EINVAL;
+}
+
+static void i2c_imx_dma_free(struct imx_i2c_struct *i2c_imx)
+{
+	struct imx_i2c_dma *dma = i2c_imx->dma;
+
+	dma->dma_buf = 0;
+	dma->dma_len = 0;
+
+	dma_release_channel(dma->chan_tx);
+	dma->chan_tx = NULL;
+
+	dma_release_channel(dma->chan_rx);
+	dma->chan_rx = NULL;
+
+	dma->chan_using = NULL;
+}
+
 /** Functions for IMX I2C adapter driver ***************************************
 *******************************************************************************/
 
@@ -382,6 +542,7 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
 	i2c_imx->stopped = 0;
 
 	temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK;
+	temp &= ~I2CR_DMAEN;
 	imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
 	return result;
 }
@@ -395,6 +556,8 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
 		dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 		temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
 		temp &= ~(I2CR_MSTA | I2CR_MTX);
+		if (i2c_imx->dma)
+			temp &= ~I2CR_DMAEN;
 		imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
 	}
 	if (is_imx1_i2c(i2c_imx)) {
@@ -435,6 +598,159 @@ static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
 	return IRQ_NONE;
 }
 
+static int i2c_imx_dma_write(struct imx_i2c_struct *i2c_imx,
+					struct i2c_msg *msgs)
+{
+	int result;
+	unsigned int temp = 0;
+	unsigned long orig_jiffies = jiffies;
+	struct imx_i2c_dma *dma = i2c_imx->dma;
+	struct device *dev = &i2c_imx->adapter.dev;
+
+	dma->chan_using = dma->chan_tx;
+	dma->dma_transfer_dir = DMA_MEM_TO_DEV;
+	dma->dma_data_dir = DMA_TO_DEVICE;
+	dma->dma_len = msgs->len - 1;
+	result = i2c_imx_dma_xfer(i2c_imx, msgs);
+	if (result)
+		return result;
+
+	temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
+	temp |= I2CR_DMAEN;
+	imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
+
+	/*
+	 * Write slave address.
+	 * The first byte must be transmitted by the CPU.
+	 */
+	imx_i2c_write_reg(msgs->addr << 1, i2c_imx, IMX_I2C_I2DR);
+	reinit_completion(&i2c_imx->dma->cmd_complete);
+	result = wait_for_completion_timeout(
+				&i2c_imx->dma->cmd_complete,
+				msecs_to_jiffies(DMA_TIMEOUT));
+	if (result <= 0) {
+		dmaengine_terminate_all(dma->chan_using);
+		return result ?: -ETIMEDOUT;
+	}
+
+	/* Waiting for transfer complete. */
+	while (1) {
+		temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
+		if (temp & I2SR_ICF)
+			break;
+		if (time_after(jiffies, orig_jiffies +
+				msecs_to_jiffies(DMA_TIMEOUT))) {
+			dev_dbg(dev, "<%s> Timeout\n", __func__);
+			return -ETIMEDOUT;
+		}
+		schedule();
+	}
+
+	temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
+	temp &= ~I2CR_DMAEN;
+	imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
+
+	/* The last data byte must be transferred by the CPU. */
+	imx_i2c_write_reg(msgs->buf[msgs->len-1],
+				i2c_imx, IMX_I2C_I2DR);
+	result = i2c_imx_trx_complete(i2c_imx);
+	if (result)
+		return result;
+
+	result = i2c_imx_acked(i2c_imx);
+	if (result)
+		return result;
+
+	return 0;
+}
+
+static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx,
+			struct i2c_msg *msgs, bool is_lastmsg)
+{
+	int result;
+	unsigned int temp;
+	unsigned long orig_jiffies = jiffies;
+	struct imx_i2c_dma *dma = i2c_imx->dma;
+	struct device *dev = &i2c_imx->adapter.dev;
+
+	temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
+	temp |= I2CR_DMAEN;
+	imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
+
+	dma->chan_using = dma->chan_rx;
+	dma->dma_transfer_dir = DMA_DEV_TO_MEM;
+	dma->dma_data_dir = DMA_FROM_DEVICE;
+	/* The last two data bytes must be transferred by the CPU. */
+	dma->dma_len = msgs->len - 2;
+	result = i2c_imx_dma_xfer(i2c_imx, msgs);
+	if (result)
+		return result;
+
+	reinit_completion(&i2c_imx->dma->cmd_complete);
+	result = wait_for_completion_timeout(
+				&i2c_imx->dma->cmd_complete,
+				msecs_to_jiffies(DMA_TIMEOUT));
+	if (result <= 0) {
+		dmaengine_terminate_all(dma->chan_using);
+		return result ?: -ETIMEDOUT;
+	}
+
+	/* waiting for transfer complete. */
+	while (1) {
+		temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
+		if (temp & I2SR_ICF)
+			break;
+		if (time_after(jiffies, orig_jiffies +
+				msecs_to_jiffies(DMA_TIMEOUT))) {
+			dev_dbg(dev, "<%s> Timeout\n", __func__);
+			return -ETIMEDOUT;
+		}
+		schedule();
+	}
+
+	temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
+	temp &= ~I2CR_DMAEN;
+	imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
+
+	/* read n-1 byte data */
+	temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
+	temp |= I2CR_TXAK;
+	imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
+
+	msgs->buf[msgs->len-2] = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
+	/* read n byte data */
+	result = i2c_imx_trx_complete(i2c_imx);
+	if (result)
+		return result;
+
+	if (is_lastmsg) {
+		/*
+		 * It must generate STOP before read I2DR to prevent
+		 * controller from generating another clock cycle
+		 */
+		dev_dbg(dev, "<%s> clear MSTA\n", __func__);
+		temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
+		temp &= ~(I2CR_MSTA | I2CR_MTX);
+		imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
+		i2c_imx_bus_busy(i2c_imx, 0);
+		i2c_imx->stopped = 1;
+	} else {
+		/*
+		 * For i2c master receiver repeat restart operation like:
+		 * read -> repeat MSTA -> read/write
+		 * The controller must set MTX before read the last byte in
+		 * the first read operation, otherwise the first read cost
+		 * one extra clock cycle.
+		 */
+		temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+		temp |= I2CR_MTX;
+		writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+	}
+	msgs->buf[msgs->len-1] = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
+
+	return 0;
+}
+
 static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
 {
 	int i, result;
@@ -504,6 +820,9 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo
 
 	dev_dbg(&i2c_imx->adapter.dev, "<%s> read data\n", __func__);
 
+	if (i2c_imx->dma && msgs->len >= DMA_THRESHOLD && !block_data)
+		return i2c_imx_dma_read(i2c_imx, msgs, is_lastmsg);
+
 	/* read data */
 	for (i = 0; i < msgs->len; i++) {
 		u8 len = 0;
@@ -618,8 +937,12 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
 #endif
 		if (msgs[i].flags & I2C_M_RD)
 			result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg);
-		else
-			result = i2c_imx_write(i2c_imx, &msgs[i]);
+		else {
+			if (i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD)
+				result = i2c_imx_dma_write(i2c_imx, &msgs[i]);
+			else
+				result = i2c_imx_write(i2c_imx, &msgs[i]);
+		}
 		if (result)
 			goto fail0;
 	}
@@ -654,6 +977,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
 	struct imxi2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
 	void __iomem *base;
 	int irq, ret;
+	dma_addr_t phy_addr;
 
 	dev_dbg(&pdev->dev, "<%s>\n", __func__);
 
@@ -668,6 +992,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
+	phy_addr = (dma_addr_t)res->start;
 	i2c_imx = devm_kzalloc(&pdev->dev, sizeof(*i2c_imx), GFP_KERNEL);
 	if (!i2c_imx)
 		return -ENOMEM;
@@ -742,6 +1067,9 @@ static int i2c_imx_probe(struct platform_device *pdev)
 		i2c_imx->adapter.name);
 	dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
 
+	/* Init DMA config if support*/
+	i2c_imx_dma_request(i2c_imx, phy_addr);
+
 	return 0;   /* Return OK */
 
 clk_disable:
@@ -757,6 +1085,9 @@ static int i2c_imx_remove(struct platform_device *pdev)
 	dev_dbg(&i2c_imx->adapter.dev, "adapter removed\n");
 	i2c_del_adapter(&i2c_imx->adapter);
 
+	if (i2c_imx->dma)
+		i2c_imx_dma_free(i2c_imx);
+
 	/* setup chip registers to defaults */
 	imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IADR);
 	imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IFDR);
-- 
2.1.0.27.g96db324


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v11 0/3] i2c: imx: add DMA support for freescale i2c driver
  2014-11-18 10:31 [PATCH v11 0/3] i2c: imx: add DMA support for freescale i2c driver Yuan Yao
                   ` (2 preceding siblings ...)
  2014-11-18 10:31 ` [PATCH v11 3/3] i2c: imx: add " Yuan Yao
@ 2014-11-18 15:01 ` Wolfram Sang
  3 siblings, 0 replies; 5+ messages in thread
From: Wolfram Sang @ 2014-11-18 15:01 UTC (permalink / raw)
  To: Yuan Yao
  Cc: marex, LW, mark.rutland, fugang.duan, shawn.guo, linux-kernel,
	linux-arm-kernel, linux-i2c

[-- Attachment #1: Type: text/plain, Size: 264 bytes --]

On Tue, Nov 18, 2014 at 06:31:04PM +0800, Yuan Yao wrote:
> 
> Changed in v11: 
> - Fix the bug for 'orig_jiffies' uninitialized.
> - Use wait_for_completion_timeout() instead of wait_for_completion_interruptible_timeout(). 

Applied to for-next, thanks!


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-11-18 15:01 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-18 10:31 [PATCH v11 0/3] i2c: imx: add DMA support for freescale i2c driver Yuan Yao
2014-11-18 10:31 ` [PATCH v11 1/3] i2c: imx: Sort include headers alphabetically Yuan Yao
2014-11-18 10:31 ` [PATCH v11 2/3] Documentation:add DMA support for freescale i2c driver Yuan Yao
2014-11-18 10:31 ` [PATCH v11 3/3] i2c: imx: add " Yuan Yao
2014-11-18 15:01 ` [PATCH v11 0/3] " Wolfram Sang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).