summaryrefslogtreecommitdiff
path: root/drivers/core/regmap.c
AgeCommit message (Collapse)Author
2021-05-24regmap: fix a serious pointer casting bugMarek BehĂșn
There is a serious bug in regmap_read() and regmap_write() functions where an uint pointer is cast to (void *) which is then cast to (u8 *), (u16 *), (u32 *) or (u64 *), depending on register width of the map. For example given a regmap with 16-bit register width the code int val = 0x12340000; regmap_read(map, 0, &val); only changes the lower 16 bits of val on little-endian machines. The upper 16 bits will remain 0x1234. Nobody noticed this probably because this bug can be triggered with regmap_write() only on big-endian architectures (which are not used by many people anymore), and on little endian this bug has consequences only if register width is 8 or 16 bits and also the memory place to which regmap_read() should store it's result has non-zero upper bits, which it seems doesn't happen anywhere in U-Boot normally. CI managed to trigger this bug in unit test of dm_test_devm_regmap_field when compiled for sandbox_defconfig using LTO. Fix this by utilizing an union { u8; u16; u32; u64; } and reading data into this union / writing data from this union. Signed-off-by: Marek BehĂșn <marek.behun@nic.cz> Cc: Simon Glass <sjg@chromium.org> Cc: Heiko Schocher <hs@denx.de> Cc: Bin Meng <bmeng.cn@gmail.com> Cc: Pratyush Yadav <p.yadav@ti.com>
2021-02-02common: Drop asm/global_data.h from common headerSimon Glass
Move this out of the common header and include it only where needed. In a number of cases this requires adding "struct udevice;" to avoid adding another large header or in other cases replacing / adding missing header files that had been pulled in, very indirectly. Finally, we have a few cases where we did not need to include <asm/global_data.h> at all, so remove that include. Signed-off-by: Simon Glass <sjg@chromium.org> Signed-off-by: Tom Rini <trini@konsulko.com>
2020-12-13dm: treewide: Rename ..._platdata variables to just ..._platSimon Glass
Try to maintain some consistency between these variables by using _plat as a suffix for them. Signed-off-by: Simon Glass <sjg@chromium.org>
2020-09-30regmap: Add support for regmap fieldsJean-Jacques Hiblot
A regmap field is an abstraction available in Linux. It provides to access bitfields in a regmap without having to worry about shifts and masks. Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com> Reviewed-by: Simon Glass <sjg@chromium.org> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
2020-09-30regmap: Allow devices to specify regmap range start and size in configPratyush Yadav
Some devices need to calculate the regmap base address at runtime. This makes it impossible to use device tree to get the regmap base. Instead, allow devices to specify it in the regmap config. This will create a regmap with a single range that corresponds to the start and size given by the driver. Signed-off-by: Pratyush Yadav <p.yadav@ti.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2020-09-30regmap: Add regmap_init_mem_range()Pratyush Yadav
Right now, the base of a regmap can only be obtained from the device tree. This makes it impossible for devices which calculate the base at runtime to use a regmap. An example of such a device is the Cadence Sierra PHY. Allow creating a regmap with one range whose start and size can be specified by the driver based on calculations at runtime. Signed-off-by: Pratyush Yadav <p.yadav@ti.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2020-09-30regmap: Allow left shifting register offset before accessPratyush Yadav
Drivers can configure it to adjust the final read/write location. Signed-off-by: Pratyush Yadav <p.yadav@ti.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2020-09-30regmap: Allow specifying read/write widthPratyush Yadav
Right now, regmap_read() and regmap_write() read/write a 32-bit value only. To write other lengths, regmap_raw_read() and regmap_raw_write() need to be used. This means that any driver ported from Linux that relies on regmap_{read,write}() to know the size already has to be updated at each callsite. This makes the port harder to maintain. So, allow specifying the read/write width to make it easier to port the drivers, since now the only change needed is when initializing the regmap. Signed-off-by: Pratyush Yadav <p.yadav@ti.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2020-09-30regmap: zero out the regmap on allocationPratyush Yadav
Some fields will be introduced in the regmap structure that should be set to 0 by default. So, once we allocate a regmap, make sure it is zeroed out to avoid unexpected defaults for those values. Signed-off-by: Pratyush Yadav <p.yadav@ti.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2020-09-30regmap: Add devm_regmap_init()Jean-Jacques Hiblot
Most of new linux drivers are using managed-API to allocate resources. To ease porting drivers from linux to U-Boot, introduce devm_regmap_init() as a managed API to get a regmap from the device tree. Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com> Reviewed-by: Simon Glass <sjg@chromium.org> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
2020-06-11regmap: Check for out-of-range offsets before mapping themPratyush Yadav
In regmap_raw_{read,write}_range(), offsets are checked to make sure they aren't out of range. But this check happens _after_ the address is mapped from physical memory. Input should be sanity-checked before using it. Mapping the address before validating it leaves the door open to passing an invalid address to map_physmem(). So check for out of range offsets _before_ mapping them. This fixes a segmentation fault in sandbox when -1 is used as an offset to regmap_{read,write}(). Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
2020-05-18common: Drop log.h from common headerSimon Glass
Move this header out of the common header. Signed-off-by: Simon Glass <sjg@chromium.org>
2019-12-03regmap: Fix potential memory leaksFaiz Abbas
Free allocated memory in case of an error in regmap_init_mem() and regmap_init_mem_index(). Signed-off-by: Faiz Abbas <faiz_abbas@ti.com>
2019-10-27dm: regmap: Fix mask in regmap_update_bits()Simon Glass
This function assumes that the 'val' parameter has no masked bits set. This is not defined by the function prototype though. Fix the function to mask the value and update the documentation. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Reviewed-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
2019-07-17regmap: Add API regmap_init_mem_index()Faiz Abbas
In device nodes with more than one entry in the reg property, it is sometimes useful to regmap only of the entries. Add an API regmap_init_mem_index() to facilitate this. Signed-off-by: Faiz Abbas <faiz_abbas@ti.com> Reviewed-by: Tom Rini <trini@konsulko.com>
2018-11-14regmap: Add endianness supportMario Six
Add support for switching the endianness of regmap accesses via the "little-endian", "big-endian", and "native-endian" boolean properties in the device tree. The default endianness is native endianness. Signed-off-by: Mario Six <mario.six@gdsys.cc> Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2018-11-14regmap: Support reading from specific rangeMario Six
It is useful to be able to treat the different ranges of a regmap separately to be able to use distinct offset for them, but this is currently not implemented in the regmap API. To preserve backwards compatibility, add regmap_read_range and regmap_write_range functions that take an additional parameter 'range_num' that identifies the range to operate on. Reviewed-by: Anatolij Gustschin <agust@denx.de> Reviewed-by: Simon Glass <sjg@chromium.org> Signed-off-by: Mario Six <mario.six@gdsys.cc>
2018-11-14regmap: Add raw read/write functionsMario Six
The regmap functions currently assume that all register map accesses have a data width of 32 bits, but there are maps that have different widths. To rectify this, implement the regmap_raw_read and regmap_raw_write functions from the Linux kernel API that specify the width of a desired read or write operation on a regmap. Implement the regmap_read and regmap_write functions using these raw functions in a backwards-compatible manner. Reviewed-by: Anatolij Gustschin <agust@denx.de> Signed-off-by: Mario Six <mario.six@gdsys.cc> Reviewed-by: Simon Glass <sjg@chromium.org>
2018-11-14regmap: Add error outputMario Six
Add some debug output in cases where the initialization of a regmap fails. Reviewed-by: Anatolij Gustschin <agust@denx.de> Reviewed-by: Simon Glass <sjg@chromium.org> Signed-off-by: Mario Six <mario.six@gdsys.cc>
2018-11-14regmap: Introduce init_rangeMario Six
Both fdtdec_get_addr_size_fixed and of_address_to_resource can fail with an error, which is not currently checked during regmap initialization. Since the indentation depth is already quite deep, extract a new 'init_range' method to do the initialization. Reviewed-by: Anatolij Gustschin <agust@denx.de> Reviewed-by: Simon Glass <sjg@chromium.org> Signed-off-by: Mario Six <mario.six@gdsys.cc>
2018-11-14regmap: Improve error handlingMario Six
ofnode_read_simple_addr_cells may fail and return a negative error code. Check for this when initializing regmaps. Also check if both_len is zero, since this is perfectly possible, and would lead to a division-by-zero further down the line. Reviewed-by: Anatolij Gustschin <agust@denx.de> Reviewed-by: Simon Glass <sjg@chromium.org> Signed-off-by: Mario Six <mario.six@gdsys.cc>
2018-11-14regmap: Add documentationMario Six
Document the regmap_alloc() function. Reviewed-by: Anatolij Gustschin <agust@denx.de> Reviewed-by: Simon Glass <sjg@chromium.org> Signed-off-by: Mario Six <mario.six@gdsys.cc>
2018-05-08regmap: add regmap_update_bits() helperNeil Armstrong
Add the regmap_update_bits() to simply the read/modify/write of registers in a single command. The function is taken from Linux regmap implementation. Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2018-05-07regmap: change regmap_init_mem() to take ofnode instead udeviceMasahiro Yamada
Currently, regmap_init_mem() takes a udevice. This requires the node has already been associated with a device. It prevents syscon/regmap from behaving like those in Linux. Change the first argumenet to take a device node. Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com> Acked-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2018-05-07regmap: clean up regmap allocationMasahiro Yamada
Putting zero length array at the end of struct is a common technique to embed arbitrary length of members. There is no good reason to let regmap_alloc_count() branch by "if (count <= 1)". As far as I understood the code, regmap->base is an alias of regmap->ranges[0].start, but it is not helpful but make the code just ugly. Rename regmap_alloc_count() to regmap_alloc() because the _count suffix seems pointless. Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com> Reviewed-by: Simon Glass <sjg@chromium.org> [trini: fixup cpu_info-rcar.c] Signed-off-by: Tom Rini <trini@konsulko.com>
2018-05-07SPDX: Convert all of our single license tags to Linux Kernel styleTom Rini
When U-Boot started using SPDX tags we were among the early adopters and there weren't a lot of other examples to borrow from. So we picked the area of the file that usually had a full license text and replaced it with an appropriate SPDX-License-Identifier: entry. Since then, the Linux Kernel has adopted SPDX tags and they place it as the very first line in a file (except where shebangs are used, then it's second line) and with slightly different comment styles than us. In part due to community overlap, in part due to better tag visibility and in part for other minor reasons, switch over to that style. This commit changes all instances where we have a single declared license in the tag as both the before and after are identical in tag contents. There's also a few places where I found we did not have a tag and have introduced one. Signed-off-by: Tom Rini <trini@konsulko.com>
2018-03-05libfdt: move headers to <linux/libfdt.h> and <linux/libfdt_env.h>Masahiro Yamada
Thomas reported U-Boot failed to build host tools if libfdt-devel package is installed because tools include libfdt headers from /usr/include/ instead of using internal ones. This commit moves the header code: include/libfdt.h -> include/linux/libfdt.h include/libfdt_env.h -> include/linux/libfdt_env.h and replaces include directives: #include <libfdt.h> -> #include <linux/libfdt.h> #include <libfdt_env.h> -> #include <linux/libfdt_env.h> Reported-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
2017-09-15dtoc: Add support for 32 or 64-bit addressesSimon Glass
When using 32-bit addresses dtoc works correctly. For 64-bit addresses it does not since it ignores the #address-cells and #size-cells properties. Update the tool to use fdt64_t as the element type for reg properties when either the address or size is larger than one cell. Use the correct value so that C code can obtain the information from the device tree easily. Alos create a new type, fdt_val_t, which is defined to either fdt32_t or fdt64_t depending on the word size of the machine. This type corresponds to fdt_addr_t and fdt_size_t. Unfortunately we cannot just use those types since they are defined to phys_addr_t and phys_size_t which use 'unsigned long' in the 32-bit case, rather than 'unsigned int'. Add tests for the four combinations of address and size values (32/32, 64/64, 32/64, 64/32). Also update existing uses for rk3399 and rk3368 which now need to use the new fdt_val_t type. Signed-off-by: Simon Glass <sjg@chromium.org> Suggested-by: Heiko Stuebner <heiko@sntech.de> Reported-by: Kever Yang <kever.yang@rock-chips.com> Reviewed-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com> Tested-by: Kever Yang <kever.yang@rock-chips.com>
2017-07-11dm: core: Add functions to obtain node's address/size cellsSimon Glass
The of_n_addr_cells() and of_n_size_cells() functions are useful for getting the size of addresses in a node, but in a few places U-Boot needs to obtain the actual property value for a node without walking up the stack. Add functions for this and just the existing code to use it. Add a comment to the existing ofnode functions which do not do the right thing with a flat tree. This fixes a problem reading PCI addresses. Signed-off-by: Simon Glass <sjg@chromium.org> Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com> Tested-on: Beaver, Jetson-TK1
2017-06-01dm: regmap: Add support for livetreeSimon Glass
Modify regmap to support livetree. Signed-off-by: Simon Glass <sjg@chromium.org>
2017-06-01dm: core: Replace of_offset with accessor (part 2)Simon Glass
At present devices use a simple integer offset to record the device tree node associated with the device. In preparation for supporting a live device tree, which uses a node pointer instead, refactor existing code to access this field through an inline function. Signed-off-by: Simon Glass <sjg@chromium.org>
2017-03-22regmap: use fdt address translationJean-Jacques Hiblot
In the DTS, the addresses are defined relative to the parent bus. We need to translate them to get the address as seen by the CPU core. Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
2017-02-08dm: core: Replace of_offset with accessorSimon Glass
At present devices use a simple integer offset to record the device tree node associated with the device. In preparation for supporting a live device tree, which uses a node pointer instead, refactor existing code to access this field through an inline function. Signed-off-by: Simon Glass <sjg@chromium.org>
2016-09-21dm: regmap: Implement simple regmap_read & regmap_writePaul Burton
The regmap_read & regmap_write functions were previously declared in regmap.h but not implemented anywhere. The regmap implementation & commit message of 6f98b7504f70 ("dm: Add support for register maps (regmap)") indicate that only memory mapped accesses are supported for now, so providing simple implementations of regmap_read & regmap_write is trivial. The access size is presumed to be 4 bytes & endianness is presumed native, which are the defaults for the regmap code in Linux. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2016-07-14dm: core: Add an implementation of regmap_init_mem_platdata()Simon Glass
Add an implementation of this function which mirrors the functions of the automatic device-tree implementation. This can be used with of-platdata to create regmaps. Signed-off-by: Simon Glass <sjg@chromium.org>
2016-07-14dm: core: Move regmap allocation into a separate functionSimon Glass
We plan to add a new way of creating a regmap for of-platdata. Move the allocation code into a separate function so that it can be shared. Signed-off-by: Simon Glass <sjg@chromium.org>
2016-07-14dm: regmap: Add a dummy implementation for of-platdataSimon Glass
Add a placeholder for now so that this code will compile. It currently does nothing. Signed-off-by: Simon Glass <sjg@chromium.org>
2015-07-21dm: Add support for register maps (regmap)Simon Glass
Add a simple implementaton of register maps, supporting only direct I/O for now. This can be enhanced later to support buses which have registers, such as I2C, SPI and PCI. It allows drivers which can operate with multiple buses to avoid dealing with the particulars of register access on that bus. Signed-off-by: Simon Glass <sjg@chromium.org>