Age | Commit message (Collapse) | Author |
|
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core and debugfs updates from Greg KH:
"Here is the "big" driver core and debugfs changes for 5.3-rc1
It's a lot of different patches, all across the tree due to some api
changes and lots of debugfs cleanups.
Other than the debugfs cleanups, in this set of changes we have:
- bus iteration function cleanups
- scripts/get_abi.pl tool to display and parse Documentation/ABI
entries in a simple way
- cleanups to Documenatation/ABI/ entries to make them parse easier
due to typos and other minor things
- default_attrs use for some ktype users
- driver model documentation file conversions to .rst
- compressed firmware file loading
- deferred probe fixes
All of these have been in linux-next for a while, with a bunch of
merge issues that Stephen has been patient with me for"
* tag 'driver-core-5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (102 commits)
debugfs: make error message a bit more verbose
orangefs: fix build warning from debugfs cleanup patch
ubifs: fix build warning after debugfs cleanup patch
driver: core: Allow subsystems to continue deferring probe
drivers: base: cacheinfo: Ensure cpu hotplug work is done before Intel RDT
arch_topology: Remove error messages on out-of-memory conditions
lib: notifier-error-inject: no need to check return value of debugfs_create functions
swiotlb: no need to check return value of debugfs_create functions
ceph: no need to check return value of debugfs_create functions
sunrpc: no need to check return value of debugfs_create functions
ubifs: no need to check return value of debugfs_create functions
orangefs: no need to check return value of debugfs_create functions
nfsd: no need to check return value of debugfs_create functions
lib: 842: no need to check return value of debugfs_create functions
debugfs: provide pr_fmt() macro
debugfs: log errors when something goes wrong
drivers: s390/cio: Fix compilation warning about const qualifiers
drivers: Add generic helper to match by of_node
driver_find_device: Unify the match function with class_find_device()
bus_find_device: Unify the match callback with class_find_device
...
|
|
|
|
In the new SPI ACPI slave enumeration code, we use the value of
lookup.max_speed_khz as a flag to decide whether a match occurred.
However, doing so only makes sense if we initialize its value to
zero beforehand, or otherwise, random junk from the stack will
cause spurious matches.
So zero initialize the lookup struct fully, and only set the non-zero
members explicitly.
Fixes: 4c3c59544f33 ("spi/acpi: enumerate all SPI slaves in the namespace")
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: andy.shevchenko@gmail.com
Cc: masahisa.kojima@linaro.org
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Cc: linux-acpi@vger.kernel.org
Cc: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
There is an arbitrary difference between the prototypes of
bus_find_device() and class_find_device() preventing their callers
from passing the same pair of data and match() arguments to both of
them, which is the const qualifier used in the prototype of
class_find_device(). If that qualifier is also used in the
bus_find_device() prototype, it will be possible to pass the same
match() callback function to both bus_find_device() and
class_find_device(), which will allow some optimizations to be made in
order to avoid code duplication going forward. Also with that, constify
the "data" parameter as it is passed as a const to the match function.
For this reason, change the prototype of bus_find_device() to match
the prototype of class_find_device() and adjust its callers to use the
const qualifier in accordance with the new prototype of it.
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Andreas Noever <andreas.noever@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Corey Minyard <minyard@acm.org>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: David Kershner <david.kershner@unisys.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: David Airlie <airlied@linux.ie>
Cc: Felipe Balbi <balbi@kernel.org>
Cc: Frank Rowand <frowand.list@gmail.com>
Cc: Grygorii Strashko <grygorii.strashko@ti.com>
Cc: Harald Freudenberger <freude@linux.ibm.com>
Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Heiko Stuebner <heiko@sntech.de>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Jonathan Cameron <jic23@kernel.org>
Cc: "James E.J. Bottomley" <jejb@linux.ibm.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Mark Brown <broonie@kernel.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Michael Jamet <michael.jamet@intel.com>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Peter Oberparleiter <oberpar@linux.ibm.com>
Cc: Sebastian Ott <sebott@linux.ibm.com>
Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Cc: Yehezkel Bernat <YehezkelShB@gmail.com>
Cc: rafael@kernel.org
Acked-by: Corey Minyard <minyard@acm.org>
Acked-by: David Kershner <david.kershner@unisys.com>
Acked-by: Mark Brown <broonie@kernel.org>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Acked-by: Wolfram Sang <wsa@the-dreams.de> # for the I2C parts
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
at91sam9g25ek showed the following error at probe:
atmel_spi f0000000.spi: Using dma0chan2 (tx) and dma0chan3 (rx)
for DMA transfers
atmel_spi: probe of f0000000.spi failed with error -22
Commit 0a919ae49223 ("spi: Don't call spi_get_gpio_descs() before device name is set")
moved the calling of spi_get_gpio_descs() after ctrl->dev is set,
but didn't move the !ctrl->num_chipselect check. When there are
chip selects in the device tree, the spi-atmel driver lets the
SPI core discover them when registering the SPI master.
The ctrl->num_chipselect is thus expected to be set by
spi_get_gpio_descs().
Move the !ctlr->num_chipselect after spi_get_gpio_descs() as it was
before the aforementioned commit. While touching this block, get rid
of the explicit comparison with 0 and update the commenting style.
Fixes: 0a919ae49223 ("spi: Don't call spi_get_gpio_descs() before device name is set")
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
The ACPI device object parsing code for SPI slaves enumerates the
entire ACPI namespace to look for devices that refer to the master
in question via the 'resource_source' field in the 'SPISerialBus'
resource. If that field does not refer to a valid ACPI device or
if it refers to the wrong SPI master, we should disregard the
device.
Current, the valid device check is wrong, since it gets the
polarity of 'status' wrong. This could cause issues if the
'resource_source' field is bogus but parent_handle happens to
refer to the correct master (which is not entirely imaginary
since this code runs in a loop)
So test for ACPI_FAILURE() instead, to make the code more
self explanatory.
Fixes: 4c3c59544f33 ("spi/acpi: enumerate all SPI slaves in the namespace")
Reported-by: kbuild test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: andy.shevchenko@gmail.com
Cc: masahisa.kojima@linaro.org
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Cc: linux-acpi@vger.kernel.org
Cc: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
The loop declaration in function spi_res_release() can be simplified
by reusing the common list_for_each_entry_safe_reverse() helper
macro.
Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
The device_for_each_child() doesn't require the returned value to be checked.
Thus, drop the dummy variable completely and have no warning anymore:
drivers/spi/spi.c: In function ‘spi_unregister_controller’:
drivers/spi/spi.c:2480:6: warning: variable ‘dummy’ set but not used [-Wunused-but-set-variable]
int dummy;
^~~~~
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Currently, the ACPI enumeration that takes place when registering a
SPI master only considers immediate child devices in the ACPI namespace,
rather than checking the ResourceSource field in the SpiSerialBus()
resource descriptor.
This is incorrect: SPI slaves could reside anywhere in the ACPI
namespace, and so we should enumerate the entire namespace and look for
any device that refers to the newly registered SPI master in its
resource descriptor.
So refactor the existing code and use a lookup structure so that
allocating the SPI device structure is deferred until we have identified
the device as an actual child of the controller. This approach is
loosely based on the way the I2C subsystem handles ACPI enumeration.
Note that Apple x86 hardware does not rely on SpiSerialBus() resources
in _CRS but uses nested devices below the controller's device node in
the ACPI namespace, with a special set of device properties. This means
we have to take care to only parse those properties for device nodes
that are direct children of the controller node.
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: linux-spi@vger.kernel.org
Cc: broonie@kernel.org
Cc: andy.shevchenko@gmail.com
Cc: masahisa.kojima@linaro.org
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Cc: linux-acpi@vger.kernel.org
Cc: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
One of the more common cases of allocation size calculations is finding
the size of a structure that has a zero-sized array at the end, along
with memory for some number of elements for that array. For example:
struct spi_replaced_transfers {
...
struct spi_transfer inserted_transfers[];
};
Make use of the struct_size() helper instead of an open-coded version
in order to avoid any potential type mistakes.
So, replace the following form:
insert * sizeof(struct spi_transfer) + sizeof(struct spi_replaced_transfers)
with:
struct_size(rxfer, inserted_transfers, insert)
This code was detected with the help of Coccinelle.
Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
Right now the only way to get the SPI pumping thread bumped up to
realtime priority is for the controller to request it. However it may
be that the controller works fine with the normal priority but
communication to a particular SPI device on the bus needs realtime
priority.
Let's add a way for devices to request realtime priority when they set
themselves up.
NOTE: this will just affect the priority of transfers that end up on
the SPI core's pumping thread. In many cases transfers happen in the
context of the caller so if you need realtime priority for all
transfers you should ensure the calling context is also realtime
priority.
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Tested-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
There is no chance to wait spi message complete if failed to
prepare_transfer_hardware(). Therefore, finalize this message and abort
transfer with corresponding return status to release this block case.
Logs:
[17400.283005] c7 3267 PM: PM: suspend entry 2019-05-04 03:01:14.403097147 UTC
[17400.283013] c7 3267 PM: suspend entry (deep)
[17400.283016] c6 3267 PM: Syncing filesystems ... done.
[17400.584395] c1 753 spi_geni 890000.spi: spi_geni_prepare_transfer_hardware:Error enabling SE resources -13
[17400.584404] c1 753 spi_master spi1: failed to prepare transfer hardware
[17400.664611] c4 3267 PM: PM: suspend exit 2019-05-04 03:01:15.235273018 UTC
Flow:
__spi_sync@spi.c
| if (status == 0) {
| /* Push out the messages in the calling context if we
| * can.
| */
| if (ctlr->transfer == spi_queued_transfer) {
| SPI_STATISTICS_INCREMENT_FIELD(&ctlr->statistics,
| spi_sync_immediate);
| SPI_STATISTICS_INCREMENT_FIELD(&spi->statistics,
| spi_sync_immediate);
| __spi_pump_messages(ctlr, false);
| }
|
| wait_for_completion(&done); <== stuck here!!!
| status = message->status;
| }
| message->context = NULL;
| return status;
|
--> __spi_pump_messages@spi.c
| if (!was_busy && ctlr->prepare_transfer_hardware) {
| ret = ctlr->prepare_transfer_hardware(ctlr);
| if (ret) {
| dev_err(&ctlr->dev,
| "failed to prepare transfer hardware\n");
|
| if (ctlr->auto_runtime_pm)
| pm_runtime_put(ctlr->dev.parent);
| mutex_unlock(&ctlr->io_mutex);
| return;
| }
| }
|
--> spi_geni_prepare_transfer_hardware@spi-geni-qcom.c
| ret = pm_runtime_get_sync(mas->dev);
| if (ret < 0) {
| dev_err(mas->dev,
| "%s:Error enabling SE resources %d\n",
| __func__, ret);
| pm_runtime_put_noidle(mas->dev);
| goto exit_prepare_transfer_hardware;
Signed-off-by: Super Liu <supercjliu@google.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Provide a means for the spi bus driver to report the effectively used
spi clock frequency used for each spi_transfer.
Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
This reverts commit c9ba7a16d0f1 (Release spi_res after finalizing
message) which causes races during cleanup.
Reported-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Support setting a delay between cs assert and deassert as
a multiple of spi clock length.
Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
For some SPI devices that support speed_hz > 1MHz the default 10 us delay
when cs_change = 1 is typically way to long and may result in poor spi bus
utilization.
This patch makes it possible to control the delay at micro or nano second
resolution on a per spi_transfer basis. It even allows an "as fast as
possible" mode with:
xfer.cs_change_delay_unit = SPI_DELAY_UNIT_NSECS;
xfer.cs_change_delay = 0;
The delay code is shared between delay_usecs and cs_change_delay for
consistency and reuse, so in the future this change_delay_unit could also
apply to delay_usec as well.
Note that on slower SOCs/CPU actually reaching ns deasserts on cs is not
realistic as the gpio overhead alone (without any delays added ) may
already leave cs deasserted for more than 1us - at least on a raspberry pi.
But at the very least this way we can keep it as short as possible.
Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
When GPIO chip-select is used nothing prevents any available SPI
controllers to work with both CS-high and traditional CS-low modes.
In fact the SPI bus core code already does it, so we don't need to
introduce any modification there. But spi_setup() still fails to
switch the interface settings if CS-high flag is set for the case
of GPIO-driven slave chip-select when the SPI controller doesn't
support the hardwired CS-inversion. Lets fix it by clearing the
SPI_CS_HIGH flag out from bad_bits (unsupported by controller) when
client chip is selected by GPIO.
This feature is useful for slave devices, which in accordance with
communication protocol can work with both active-high and active-low
chip-selects. I am aware of one such device. It is MMC-SPI interface,
when at init sequence the driver needs to perform a read operation with
low and high chip-select sequentially (requirement of 74 clock cycles
with both chipselect, see the mmc_spi driver for details).
Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
spi_split_transfers_maxsize() can be used to split a transfer. This
function uses spi_res to lifetime manage the added transfer structures.
So in order to finalize the current message while it contains the split
transfers, spi_res_release() must be called after finalizing.
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Don't warn about splitting transfers, the info is available in the
statistics if needed.
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Falling back to maximum speed of the controller in case of SPI slave
maximum speed is not set is needless. It already defaults to maximum
speed of the controller since commit 052eb2d49006 ("spi: core: Set
max_speed_hz of spi_device default to max_speed_hz of controller").
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
This patch creates set_cs_timing SPI master optional method for
SPI masters to implement configuring CS timing if applicable.
This patch also creates spi_cs_timing accessory for SPI clients to
use for requesting SPI master controllers to configure device requested
CS setup time, hold time and inactive delay.
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
The 'status' local variable is initialized but this value is never used,
thus kill that initializer.
Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Move code calling spi_get_gpio_descs() to happen after ctlr->dev's
name is set in order to have proper GPIO consumer names.
Before:
cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 0-31, parent: platform/40049000.gpio, vf610-gpio:
gpio-6 ( |regulator-usb0-vbus ) out lo
gpiochip1: GPIOs 32-63, parent: platform/4004a000.gpio, vf610-gpio:
gpio-36 ( |scl ) in hi
gpio-37 ( |sda ) in hi
gpio-40 ( |(null) CS1 ) out lo
gpio-41 ( |(null) CS0 ) out lo ACTIVE LOW
gpio-42 ( |miso ) in hi
gpio-43 ( |mosi ) in lo
gpio-44 ( |sck ) out lo
After:
cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 0-31, parent: platform/40049000.gpio, vf610-gpio:
gpio-6 ( |regulator-usb0-vbus ) out lo
gpiochip1: GPIOs 32-63, parent: platform/4004a000.gpio, vf610-gpio:
gpio-36 ( |scl ) in hi
gpio-37 ( |sda ) in hi
gpio-40 ( |spi0 CS1 ) out lo
gpio-41 ( |spi0 CS0 ) out lo ACTIVE LOW
gpio-42 ( |miso ) in hi
gpio-43 ( |mosi ) in lo
gpio-44 ( |sck ) out lo
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Chris Healy <cphealy@gmail.com>
Cc: linux-spi@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
While devm_gpiod_get_index_optional() returns NULL if the GPIO is not
present (i.e. -ENOENT), it may still return other error codes, like
-EPROBE_DEFER. Currently these are not handled, leading to
unrecoverable failures later in case of probe deferral:
gpiod_set_consumer_name: invalid GPIO (errorpointer)
gpiod_direction_output: invalid GPIO (errorpointer)
gpiod_set_value_cansleep: invalid GPIO (errorpointer)
gpiod_set_value_cansleep: invalid GPIO (errorpointer)
gpiod_set_value_cansleep: invalid GPIO (errorpointer)
Detect and propagate errors to fix this.
Fixes: f3186dd876697e69 ("spi: Optionally use GPIO descriptors for CS GPIOs")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
The newly added tracepoints in the spi-mxs driver cause a link
error when the driver is a loadable module:
ERROR: "__tracepoint_spi_transfer_stop" [drivers/spi/spi-mxs.ko] undefined!
ERROR: "__tracepoint_spi_transfer_start" [drivers/spi/spi-mxs.ko] undefined!
I'm not quite sure where to put the export statements, but
directly after the inclusion of the header seems as good as
any other place.
Fixes: f3fdea3af405 ("spi: mxs: add tracing to custom .transfer_one_message callback")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
This fixes a bug for messages containing both zero length and
unidirectional xfers.
The function spi_map_msg will allocate dummy tx and/or rx buffers
for use with unidirectional transfers when the hardware can only do
a bidirectional transfer. That dummy buffer will be used in place
of a NULL buffer even when the xfer length is 0.
Then in the function __spi_map_msg, if he hardware can dma,
the zero length xfer will have spi_map_buf called on the dummy
buffer.
Eventually, __sg_alloc_table is called and returns -EINVAL
because nents == 0.
This fix prevents the error by not using the dummy buffer when
the xfer length is zero.
Signed-off-by: Chris Lesiak <chris.lesiak@licor.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Sleeping is safe inside spi_transfer_one_message, and some
GPIO chips are running on slow busses (such as I2C GPIO
expanders) and need to sleep for setting values.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Some devices are slow and cannot keep up with the SPI bus and therefore
require a short delay between words of the SPI transfer.
The example of this that I'm looking at is a SAMA5D2 with a minimum SPI
clock of 400kHz talking to an AVR-based SPI slave. The AVR cannot put
bytes on the bus fast enough to keep up with the SoC's SPI controller
even at the lowest bus speed.
This patch introduces the ability to specify a required inter-word
delay for SPI devices. It is up to the controller driver to configure
itself accordingly in order to introduce the requested delay.
Note that, for spi_transfer, there is already a field word_delay that
provides similar functionality. This field, however, is specified in
clock cycles (and worse, SPI controller cycles, not SCK cycles); that
makes this value dependent on the master clock instead of the device
clock for which the delay is intended to provide some relief. This
patch leaves this old word_delay in place and provides a time-based
word_delay_us alongside it; the new field fits in the struct padding
so struct size is constant. There is only one in-kernel user of the
word_delay field and presumably that driver could be reworked to use
the time-based value instead.
The time-based delay is limited to 8 bits as these delays are intended
to be short. The SAMA5D2 that I've tested this on limits delays to a
maximum of ~100us, which is already many word-transfer periods even at
the minimum transfer speed supported by the controller.
Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
CC: Mark Brown <broonie@kernel.org>
CC: Rob Herring <robh+dt@kernel.org>
CC: Mark Rutland <mark.rutland@arm.com>
CC: linux-spi@vger.kernel.org
CC: devicetree@vger.kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
All controllers using GPIO descriptors can by definition
support high CS connections, so just enforce this when
registering an SPI controller.
This fixes a regression where controllers were missing
SPI_CS_HIGH, the drivers would fail like this:
spi spi0.0: setup: unsupported mode bits 4
cdns-spi fd0b0000.spi: can't setup spi0.0, status -22
This is because as using descriptors moves the CS inversion
logic over to gpiolib, all such controllers are registered
with CS active high.
Cc: Jan Kotas <jank@cadence.com>
Reported-by: Jan Kotas <jank@cadence.com>
Tested-by: Jan Kotas <jank@cadence.com>
Fixes: f3186dd87669 ("spi: Optionally use GPIO descriptors for CS GPIOs")
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Commit 412e6037324 ("spi: core: avoid waking pump thread from spi_sync
instead run teardown delayed") introduced regressions on some boards,
apparently connected to spi_mem not triggering shutdown properly any
more. Since we've thus far been unable to figure out exactly where the
breakage is revert the optimisation for now.
Reported-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: kernel@martin.sperl.org
|
|
When spi_sync is running alone with no other spi devices connected
to the bus the worker thread is woken during spi_finalize_current_message
to run the teardown code every time.
This is totally unnecessary in the case that there is no message queued.
On a multi-core system this results in one wakeup of the thread for each
spi_message processed via spi_sync where in most cases the teardown does
not happen as the hw is already in use.
This patch now delays the teardown by 1 second by using a separate
kthread_delayed_work for the teardown.
This avoids waking the kthread too often.
For spi_sync transfers in a tight loop (say 40k messages/s) this
avoids the penalty of waking the worker thread 40k times/s.
On a rasperry pi 3 with 4 cores the results in 32% of a single core
only to find out that there is nothing in the queue and it can go back
to sleep.
With this patch applied the spi-worker is woken exactly once: after
the load finishes and the spi bus is idle for 1 second.
I believe I have also seen situations where during a spi_sync loop
the worker thread (triggered by the last message finished) is slightly
faster and _wins_ the race to process the message, so we are actually
running the kthread and letting it do some work...
This is also no longer observed with this patch applied as.
Tested with a new CAN controller driver for the mcp2517fd which
uses spi_sync for interrupt handling and spi_async for scheduling
of can frames for transmission (in a different thread)
Some statistics when receiving 100000 CAN frames with the mcp25xxfd driver
on a Raspberry pi 3:
without the patch:
------------------
root@raspcm3:~# for x in $(pgrep spi0) $(pgrep irq/94-mcp25xxf) ; do awk '{printf "%-20s %6i\n", $2,$15}' /proc/$x/stat; done
(spi0) 5
(irq/94-mcp25xxf) 0
root@raspcm3:~# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 821960 13592 50848 0 0 80 2 1986 105 1 2 97 0 0
0 0 0 821968 13592 50876 0 0 0 0 8046 30 0 0 100 0 0
0 0 0 821936 13592 50876 0 0 0 0 8032 24 0 0 100 0 0
0 0 0 821936 13592 50876 0 0 0 0 8035 30 0 0 100 0 0
0 0 0 821936 13592 50876 0 0 0 0 8033 22 0 0 100 0 0
2 0 0 821936 13592 50876 0 0 0 0 11598 7129 0 3 97 0 0
1 0 0 821872 13592 50876 0 0 0 0 37741 59003 0 31 69 0 0
2 0 0 821840 13592 50876 0 0 0 0 37762 59078 0 29 71 0 0
2 0 0 821776 13592 50876 0 0 0 0 37593 58792 0 28 72 0 0
1 0 0 821744 13592 50876 0 0 0 0 37642 58881 0 30 70 0 0
2 0 0 821680 13592 50876 0 0 0 0 37490 58602 0 27 73 0 0
1 0 0 821648 13592 50876 0 0 0 0 37412 58418 0 29 71 0 0
1 0 0 821584 13592 50876 0 0 0 0 37337 58288 0 27 73 0 0
1 0 0 821552 13592 50876 0 0 0 0 37584 58774 0 27 73 0 0
0 0 0 821520 13592 50876 0 0 0 0 18363 20566 0 9 91 0 0
0 0 0 821520 13592 50876 0 0 0 0 8037 32 0 0 100 0 0
0 0 0 821520 13592 50876 0 0 0 0 8031 23 0 0 100 0 0
0 0 0 821520 13592 50876 0 0 0 0 8034 26 0 0 100 0 0
0 0 0 821520 13592 50876 0 0 0 0 8033 24 0 0 100 0 0
^C
root@raspcm3:~# for x in $(pgrep spi0) $(pgrep irq/94-mcp25xxf) ; do awk '{printf "%-20s %6i\n", $2,$15}' /proc/$x/stat; done
(spi0) 228
(irq/94-mcp25xxf) 794
root@raspcm3:~# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
17: 34 0 0 0 ARMCTRL-level 1 Edge 3f00b880.mailbox
27: 1 0 0 0 ARMCTRL-level 35 Edge timer
33: 1416870 0 0 0 ARMCTRL-level 41 Edge 3f980000.usb, dwc2_hsotg:usb1
34: 1 0 0 0 ARMCTRL-level 42 Edge vc4
35: 0 0 0 0 ARMCTRL-level 43 Edge 3f004000.txp
40: 1753 0 0 0 ARMCTRL-level 48 Edge DMA IRQ
42: 11 0 0 0 ARMCTRL-level 50 Edge DMA IRQ
44: 11 0 0 0 ARMCTRL-level 52 Edge DMA IRQ
45: 0 0 0 0 ARMCTRL-level 53 Edge DMA IRQ
66: 0 0 0 0 ARMCTRL-level 74 Edge vc4 crtc
69: 0 0 0 0 ARMCTRL-level 77 Edge vc4 crtc
70: 0 0 0 0 ARMCTRL-level 78 Edge vc4 crtc
77: 20 0 0 0 ARMCTRL-level 85 Edge 3f205000.i2c, 3f804000.i2c, 3f805000.i2c
78: 6346 0 0 0 ARMCTRL-level 86 Edge 3f204000.spi
80: 205 0 0 0 ARMCTRL-level 88 Edge mmc0
81: 493 0 0 0 ARMCTRL-level 89 Edge uart-pl011
89: 0 0 0 0 bcm2836-timer 0 Edge arch_timer
90: 4291 3821 2180 1649 bcm2836-timer 1 Edge arch_timer
94: 14289 0 0 0 pinctrl-bcm2835 16 Level mcp25xxfd
IPI0: 0 0 0 0 CPU wakeup interrupts
IPI1: 0 0 0 0 Timer broadcast interrupts
IPI2: 3645 242371 7919 1328 Rescheduling interrupts
IPI3: 112 543 273 194 Function call interrupts
IPI4: 0 0 0 0 CPU stop interrupts
IPI5: 1 0 0 0 IRQ work interrupts
IPI6: 0 0 0 0 completion interrupts
Err: 0
top shows 93% for the mcp25xxfd interrupt handler, 31% for spi0.
with the patch:
---------------
root@raspcm3:~# for x in $(pgrep spi0) $(pgrep irq/94-mcp25xxf) ; do awk '{printf "%-20s %6i\n", $2,$15}' /proc/$x/stat; done
(spi0) 0
(irq/94-mcp25xxf) 0
root@raspcm3:~# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
0 0 0 804768 13584 62628 0 0 0 0 8038 24 0 0 100 0 0
0 0 0 804768 13584 62628 0 0 0 0 8042 25 0 0 100 0 0
1 0 0 804704 13584 62628 0 0 0 0 9603 2967 0 20 80 0 0
1 0 0 804672 13584 62628 0 0 0 0 9828 3380 0 24 76 0 0
1 0 0 804608 13584 62628 0 0 0 0 9823 3375 0 23 77 0 0
1 0 0 804608 13584 62628 0 0 0 12 9829 3394 0 23 77 0 0
1 0 0 804544 13584 62628 0 0 0 0 9816 3362 0 22 78 0 0
1 0 0 804512 13584 62628 0 0 0 0 9817 3367 0 23 77 0 0
1 0 0 804448 13584 62628 0 0 0 0 9822 3370 0 22 78 0 0
1 0 0 804416 13584 62628 0 0 0 0 9815 3367 0 23 77 0 0
0 0 0 804352 13584 62628 0 0 0 84 9222 2250 0 14 86 0 0
0 0 0 804352 13592 62620 0 0 0 24 8131 209 0 0 93 7 0
0 0 0 804320 13592 62628 0 0 0 0 8041 27 0 0 100 0 0
0 0 0 804352 13592 62628 0 0 0 0 8040 26 0 0 100 0 0
root@raspcm3:~# for x in $(pgrep spi0) $(pgrep irq/94-mcp25xxf) ; do awk '{printf "%-20s %6i\n", $2,$15}' /proc/$x/stat; done
(spi0) 0
(irq/94-mcp25xxf) 767
root@raspcm3:~# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
17: 29 0 0 0 ARMCTRL-level 1 Edge 3f00b880.mailbox
27: 1 0 0 0 ARMCTRL-level 35 Edge timer
33: 1024412 0 0 0 ARMCTRL-level 41 Edge 3f980000.usb, dwc2_hsotg:usb1
34: 1 0 0 0 ARMCTRL-level 42 Edge vc4
35: 0 0 0 0 ARMCTRL-level 43 Edge 3f004000.txp
40: 1773 0 0 0 ARMCTRL-level 48 Edge DMA IRQ
42: 11 0 0 0 ARMCTRL-level 50 Edge DMA IRQ
44: 11 0 0 0 ARMCTRL-level 52 Edge DMA IRQ
45: 0 0 0 0 ARMCTRL-level 53 Edge DMA IRQ
66: 0 0 0 0 ARMCTRL-level 74 Edge vc4 crtc
69: 0 0 0 0 ARMCTRL-level 77 Edge vc4 crtc
70: 0 0 0 0 ARMCTRL-level 78 Edge vc4 crtc
77: 20 0 0 0 ARMCTRL-level 85 Edge 3f205000.i2c, 3f804000.i2c, 3f805000.i2c
78: 6417 0 0 0 ARMCTRL-level 86 Edge 3f204000.spi
80: 237 0 0 0 ARMCTRL-level 88 Edge mmc0
81: 489 0 0 0 ARMCTRL-level 89 Edge uart-pl011
89: 0 0 0 0 bcm2836-timer 0 Edge arch_timer
90: 4048 3704 2383 1892 bcm2836-timer 1 Edge arch_timer
94: 14287 0 0 0 pinctrl-bcm2835 16 Level mcp25xxfd
IPI0: 0 0 0 0 CPU wakeup interrupts
IPI1: 0 0 0 0 Timer broadcast interrupts
IPI2: 2361 2948 7890 1616 Rescheduling interrupts
IPI3: 65 617 301 166 Function call interrupts
IPI4: 0 0 0 0 CPU stop interrupts
IPI5: 1 0 0 0 IRQ work interrupts
IPI6: 0 0 0 0 completion interrupts
Err: 0
top shows 91% for the mcp25xxfd interrupt handler, 0% for spi0
So we see that spi0 is no longer getting scheduled wasting CPU cycles
There are a lot less context switches and corresponding Rescheduling interrupts
All of these show that this improves efficiency of the system and reduces
CPU utilization.
Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
This augments the SPI core to optionally use GPIO descriptors
for chip select on a per-master-driver opt-in basis.
Drivers using this will rely on the SPI core to look up
GPIO descriptors associated with the device, such as
when using device tree or board files with GPIO descriptor
tables.
When getting descriptors from the device tree, this will in
turn activate the code in gpiolib that was
added in commit 6953c57ab172
("gpio: of: Handle SPI chipselect legacy bindings")
which means that these descriptors are aware of the active
low semantics that is the default for SPI CS GPIO lines
and we can assume that all of these are "active high" and
thus assign SPI_CS_HIGH to all CS lines on the DT path.
The previously used gpio_set_value() would call down into
gpiod_set_raw_value() and ignore the polarity inversion
semantics.
It seems like many drivers go to great lengths to set up the
CS GPIO line as non-asserted, respecting SPI_CS_HIGH. We pull
this out of the SPI drivers and into the core, and by simply
requesting the line as GPIOD_OUT_LOW when retrieveing it from
the device and relying on the gpiolib to handle any inversion
semantics. This way a lot of code can be simplified and
removed in each converted driver.
The end goal after dealing with each driver in turn, is to
delete the non-descriptor path (of_spi_register_master() for
example) and let the core deal with only descriptors.
The different SPI drivers have complex interactions with the
core so we cannot simply change them all over, we need to use
a stepwise, bisectable approach so that each driver can be
converted and fixed in isolation.
This patch has the intended side effect of adding support for
ACPI GPIOs as it starts relying on gpiod_get_*() to get
the GPIO handle associated with the device.
Cc: Linuxarm <linuxarm@huawei.com>
Acked-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Tested-by: Fangjian (Turing) <f.fangjian@huawei.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Convert string compares of DT node names to use of_node_name_eq helper
instead. This removes direct access to the node name pointer.
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Add flags for Octal mode I/O data transfer
Required for the SPI controller which can do the data transfer (TX/RX)
on 8 data lines e.g. NXP FlexSPI controller.
SPI_TX_OCTAL: transmit with 8 wires
SPI_RX_OCTAL: receive with 8 wires
Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur@nxp.com>
Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Make everything look intentional by having a C++ comment for the whole
block, not just the SPDX line.
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
The refactoring done as part of adding the core support for handling
waiting for slave transfer dropped a conditional which meant that we
started waiting for completion of all transfers, not just those that the
controller asked for. This caused hangs and massive delays on platforms
that don't need the core delay. Re-add the delay to fix this.
Fixes: 810923f3bf06c11 (spi: Deal with slaves that return from transfer_one() unfinished)
Reported-by: Tony Lindgren <tony@atomide.com>
Tested-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Some drivers, such as spi-pxa2xx return from the transfer_one callback
immediately, idicating that the transfer will be finished asynchronously.
Normally, spi_transfer_one_message() synchronously waits for the
transfer to finish with wait_for_completion_timeout(). For slaves, we
don't want the transaction to time out as it can complete in a long time
in future. Use wait_for_completion_interruptible() instead.
Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
Acked-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
The SPI configuration state includes an SPI_NO_CS flag that disables
all CS line manipulation, for applications that want to manage their
own chip selects. However, this flag is ignored by the GPIO CS code
in the SPI framework.
Correct this omission with a trivial patch.
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
This attribute works the same was as the identically named attribute
for PCI, AMBA, and platform devices. For reference, see:
commit 3cf385713460 ("ARM: 8256/1: driver coamba: add device binding
path 'driver_override'")
commit 3d713e0e382e ("driver core: platform: add device binding path
'driver_override'")
commit 782a985d7af2 ("PCI: Introduce new device binding path using
pci_dev.driver_override")
If the name of a driver is written to this attribute, then the device
will bind to the named driver and only the named driver.
The device will bind to the driver even if the driver does not list the
device in its id table. This behavior is different than the driver's
bind attribute, which only allows binding to devices that are listed as
supported by the driver.
It can be used to bind a generic driver, like spidev, to a device.
Signed-off-by: Trent Piepho <tpiepho@impinj.com>
Reviewed-by: Jan Kundrát <jan.kundrat@cesnet.cz>
Tested-by: Jan Kundrát <jan.kundrat@cesnet.cz>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
The of_find_spi_device_by_node() helper function is useful for other
modules too. Export the funciton as GPL like all other spi helper
functions and make it available if CONFIG_OF is enabled, because it isn't
related to the CONFIG_OF_DYNAMIC context. Finally add a stub if
CONFIG_OF isn't enabled, so others must not care about it.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
Use the appropriate SPDX license identifier and drop the previous
license text.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
This modifies the condition for using the software fallback
implementation for SPI_CS_WORD when the SPI controller is using a GPIO
for the CS line. When using a GPIO for CS, the hardware implementation
won't work, so we just enable the software fallback globally in this
case.
Signed-off-by: David Lechner <david@lechnology.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
This adds a default software implementation for the SPI_CS_WORD flag for
controllers that don't have such a feature.
The SPI_CS_WORD flag indicates that the CS line should be toggled
between each word sent, not just between each transfer. The
implementation works by using existing functions to split transfers into
one-word-sized transfers and sets the cs_change bit for each of the
new transfers.
Signed-off-by: David Lechner <david@lechnology.com>
Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
If the SPI bus number is provided by a DT alias, idr_alloc() is called
twice, leading to:
WARNING: CPU: 1 PID: 1 at drivers/spi/spi.c:2179 spi_register_controller+0x11c/0x5d8
couldn't get idr
Fix this by moving the handling of fixed SPI bus numbers up, before the
DT handling code fills in ctlr->bus_num.
Fixes: 1a4327fbf4554d5b ("spi: fix IDR collision on systems with both fixed and dynamic SPI bus numbers")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
On systems where some controllers get a dynamic ID assigned and some have
a fixed number (e.g. from ACPI tables), the current implementation might
run into an IDR collision: in case of a fixed bus number is gotten by a
driver (but not marked busy in IDR tree) and a driver with dynamic bus
number gets the same ID and predictably fails.
Fix this by means of checking-in fixed IDsin IDR as far as dynamic ones
at the moment of the controller registration.
Fixes: 9b61e302210e (spi: Pick spi bus number from Linux idr or spi alias)
Signed-off-by: Kirill Kapranov <kirill.kapranov@compulab.co.il>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org
|
|
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
|