summaryrefslogtreecommitdiff
path: root/drivers/spi/spidev.c
AgeCommit message (Collapse)AuthorFilesLines
2009-07-01spi: new spi->mode bitsDavid Brownell1-6/+11
Add two new spi_device.mode bits to accomodate more protocol options, and pass them through to usermode drivers: * SPI_NO_CS ... a second 3-wire variant, where the chipselect line is removed instead of a data line; transfers are still full duplex. This obviously has STRONG protocol implications since the chipselect transitions can't be used to synchronize state transitions with the SPI master. * SPI_READY ... defines open drain signal that's pulled low to pause the clock. This defines a 5-wire variant (normal 4-wire SPI plus READY) and two 4-wire variants (READY plus each of the 3-wire flavors). Such hardware flow control can be a big win. There are ADC converters and flash chips that expose READY signals, but not many host controllers support it today. The spi_bitbang code should be changed to use SPI_NO_CS instead of its current nonportable hack. That's a mode most hardware can easily support (unlike SPI_READY). Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Cc: "Paulraj, Sandeep" <s-paulraj@ti.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-12-02spi: avoid spidev crash when device is removedWolfgang Ocker1-1/+3
I saw a kernel oops in spidev_remove() when a spidev device was registered and I unloaded the SPI master driver: Unable to handle kernel paging request for data at address 0x00000004 Faulting instruction address: 0xc01c0c50 Oops: Kernel access of bad area, sig: 11 [#1] CDSPR Modules linked in: spi_ppc4xx(-) NIP: c01c0c50 LR: c01bf9e4 CTR: c01c0c34 REGS: cec89c30 TRAP: 0300 Not tainted (2.6.27.3izt) MSR: 00021000 <ME> CR: 24000228 XER: 20000007 DEAR: 00000004, ESR: 00800000 TASK = cf889040[2070] 'rmmod' THREAD: cec88000 GPR00: 00000000 cec89ce0 cf889040 cec8e000 00000004 cec8e000 ffffffff 00000000 GPR08: 0000001c c0336380 00000000 c01c0c34 00000001 1001a338 100e0000 100df49c GPR16: 100b54c0 100df49c 100ddd20 100f05a8 100b5340 100efd68 00000000 00000000 GPR24: 100ec008 100f0428 c0327788 c0327794 cec8e0ac cec8e000 c0336380 00000000 NIP [c01c0c50] spidev_remove+0x1c/0xe4 LR [c01bf9e4] spi_drv_remove+0x2c/0x3c Call Trace: [cec89d00] [c01bf9e4] spi_drv_remove+0x2c/0x3c [cec89d10] [c01859a0] __device_release_driver+0x78/0xb4 [cec89d20] [c0185ab0] device_release_driver+0x28/0x44 [cec89d40] [c0184be8] bus_remove_device+0xac/0xd8 [cec89d60] [c0183094] device_del+0x100/0x194 [cec89d80] [c0183140] device_unregister+0x18/0x30 [cec89da0] [c01bf30c] __unregister+0x20/0x34 [cec89db0] [c0182778] device_for_each_child+0x38/0x74 [cec89de0] [c01bf2d0] spi_unregister_master+0x28/0x44 [cec89e00] [c01bfeac] spi_bitbang_stop+0x1c/0x58 [cec89e20] [d908a5e0] spi_ppc4xx_of_remove+0x24/0x7c [spi_ppc4xx] [...] IMHO a call to spi_set_drvdata() is missing in spidev_probe(). The patch below helped. Signed-off-by: Wolfgang Ocker <weo@reccoware.de> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-10-16device create: misc: convert device_create_drvdata to device_createGreg Kroah-Hartman1-4/+3
Now that device_create() has been audited, rename things back to the original call to be sane. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2008-07-24spidev: BKL removalAlan Cox1-6/+13
Another step to removing ->ioctl and to removing the BKL [dbrownell@users.sourceforge.net: take final step; BKL not needed] Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-22device create: spi: convert device_create to device_create_drvdataDavid Brownell1-2/+2
Switch over to use the shiny new device_create_drvdata() call instead of the original device_create() calls, so this continues to work after device_create() is removed. Note that this driver never had the race which motivated removing the original call; it locked correctly. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2008-07-15Merge commit 'v2.6.26' into bkl-removalJonathan Corbet1-49/+127
2008-07-04spi: fix the read path in spidevSebastian Siewior1-6/+4
This got broken by the recent "fix rmmod $spi_driver while spidev-user is active". I tested the rmmod & write path but didn't check the read path. I am sorry. The read logic changed and spidev_sync_read() + spidev_sync_write() do not return zero on success anymore but the number of bytes that has been transfered over the bus. This patch changes the logic and copy_to_user() gets called again. The write path returns the number of bytes which are written to the underlying device what may be less than the requested size. This patch makes the same change to the read path or else we request a read of 20 bytes, get 10, don't call copy to user and report to the user that we read 10 bytes. [akpm@linux-foundation.org: remove test of known-to-be-zero local] Signed-off-by: Sebastian Siewior <bigeasy@linutronix.de> Acked-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-06-21spidev: BKL pushdownJonathan Corbet1-0/+3
Add the BKL to spidev_open(), even though the existing locking looks adequate. Signed-off-by: Jonathan Corbet <corbet@lwn.net>
2008-06-06spi: fix refcount-related spidev oops-on-rmmodDavid Brownell1-30/+34
This addresses other oopsing paths in "spidev" by changing how it manages refcounting. It decouples the lifecycle of the per-device data from the class device (not just the spi device): - Use class_{create,destroy} not class_{register,unregister}. - Use device_{create,destroy} not device_{register,unregister}. - Free the per-device data only when TWO conditions are true: * Driver is unbound from underlying SPI device, and * Device is no longer open (new) Also, spi_{get,set}_drvdata not dev_{get,set}_drvdata for simpler code. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Sebastian Siewior <bigeasy@tglx.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-05-24spi: remove some spidev oops-on-rmmod pathsDavid Brownell1-13/+89
Somehow the spidev code forgot to include a critical mechanism: when the underlying device is removed (e.g. spi_master rmmod), open file descriptors must be prevented from issuing new I/O requests to that device. On penalty of the oopsing reported by Sebastian Siewior <bigeasy@tglx.de> ... This is a partial fix, adding handshaking between the lower level (SPI messaging) and the file operations using the spi_dev. (It also fixes an issue where reads and writes didn't return the number of bytes sent or received.) There's still a refcounting issue to be addressed (separately). Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Reported-by: Sebastian Siewior <bigeasy@tglx.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-10-29fix abuses of ptrdiff_tAl Viro1-3/+3
Use of ptrdiff_t in places like - if (!access_ok(VERIFY_WRITE, u_tmp->rx_buf, u_tmp->len)) + if (!access_ok(VERIFY_WRITE, (u8 __user *) + (ptrdiff_t) u_tmp->rx_buf, + u_tmp->len)) is wrong; for one thing, it's a bad C (it's what uintptr_t is for; in general we are not even promised that ptrdiff_t is large enough to hold a pointer, just enough to hold a difference between two pointers within the same object). For another, it confuses the fsck out of sparse. Use unsigned long or uintptr_t instead. There are several places misusing ptrdiff_t; fixed. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-08-12spidev warning fixDavid Brownell1-1/+3
Git rid of "warning: passing arg 2 of `access_ok' makes pointer from integer without a cast" reported on SH ... most architectures use macros in that test, SH uses inlined functions. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-08-01spidev supports more communications modesAnton Vorontsov1-3/+10
The spidev driver doesn't currently expose all SPI communications modes to userspace. This passes them all through to the driver. Two of them are potentially troublesome, in the sense that they could cause hardware conflicts on shared busses. It might be appropriate to add some privilege checks for for those modes. Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-07-17spidev compiler warning goneDavid Brownell1-2/+4
Get rid of annoying GCC warning on 32-bit platforms. drivers/spi/spidev.c: In function 'spidev_message': drivers/spi/spidev.c:184: warning: cast to pointer from integer of different size drivers/spi/spidev.c:216: warning: cast to pointer from integer of different size The trick is to add an extra cast using "ptrdiff_t" to convert the u64 to the correct size integer, and only then casting it into a "void *" pointer. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-05-24spi: potential memleak in spidev_ioctlFlorin Malita1-0/+1
'ioc' should be deallocated if __copy_from_user fails (found by Coverity - CID 1644). Signed-off-by: Florin Malita <fmalita@gmail.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-05-24spi/spidev: check message size before copyingDomen Puncer1-6/+6
Message size needs to be checked before copying, or bad things could happen. Signed-off-by: Domen Puncer <domen.puncer@telargo.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-05-17spi: fix spidev for >sizeof(long)/32 devicesDomen Puncer1-1/+1
find_first_zero_bit accepts number of bits, not longs. Signed-off-by: Domen Puncer <domen.puncer@telargo.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-05-08/dev/spidevB.C interfaceAndrea Paterniani1-0/+584
Add a filesystem API for <linux/spi/spi.h> stack. The initial version of this interface is purely synchronous. dbrownell@users.sourceforge.net: Cleaned up, bugfixed; much simplified; added preliminary documentation. Works with mdev given CONFIG_SYSFS_DEPRECATED; and presumably udev. Updated SPI_IOC_MESSAGE ioctl to full spi_message semantics, supporting groups of one or more transfers (each of which may be full duplex if desired). This is marked as EXPERIMENTAL with an explicit disclaimer that the API (notably the ioctls) is subject to change. Signed-off-by: Andrea Paterniani <a.paterniani@swapp-eng.it> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Cc: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>