Re: [PATCH] efi: skip devices without driver in efi_pause/continue_devices()
On Tue, Jan 18, 2022 at 02:43:17PM +0100, Philipp Zabel wrote: > Skip devices on the EFI bus that do not have a driver assigned. > > Fixes: f68a547deebd ("efi: add efi_device hook to be called before an image > is started") > Signed-off-by: Philipp Zabel Tested-by: Michael Olbrich Regards, Michael > --- > drivers/efi/efi-device.c | 14 -- > 1 file changed, 12 insertions(+), 2 deletions(-) > > diff --git a/drivers/efi/efi-device.c b/drivers/efi/efi-device.c > index 39724ec2f431..f91d09e8eaa5 100644 > --- a/drivers/efi/efi-device.c > +++ b/drivers/efi/efi-device.c > @@ -473,7 +473,12 @@ void efi_pause_devices(void) > bus_for_each_device(&efi_bus, dev) { > struct driver_d *drv = dev->driver; > struct efi_device *efidev = to_efi_device(dev); > - struct efi_driver *efidrv = to_efi_driver(drv); > + struct efi_driver *efidrv; > + > + if (!drv) > + continue; > + > + efidrv = to_efi_driver(drv); > > if (efidrv->dev_pause) > efidrv->dev_pause(efidev); > @@ -487,7 +492,12 @@ void efi_continue_devices(void) > bus_for_each_device(&efi_bus, dev) { > struct driver_d *drv = dev->driver; > struct efi_device *efidev = to_efi_device(dev); > - struct efi_driver *efidrv = to_efi_driver(drv); > + struct efi_driver *efidrv; > + > + if (!drv) > + continue; > + > + efidrv = to_efi_driver(drv); > > if (efidrv->dev_continue) > efidrv->dev_continue(efidev); > -- > 2.30.2 > > > ___ > barebox mailing list > barebox@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/barebox > -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 0/6] sata_mv: cleanup and error handling
From: Steffen Trumtrar Hi! The sata_mv driver in barebox only supports the ARMADA-XP and there are not really that many users. Therefore only copy mv6-specific setup from the kernel to the barebox driver. We have some specific hardware combination of ARDAMA-XP and SATA drive that fails in probing the drive on a cold start. Not always but at least in 2 of 10 boots. When the error occurs, the error registers and/or the documentation wheren't really that helpful. The only way out is hard-resetting everything and trying again to enumerate the ATA drive. That's what we do now. While at it, get the phy errata from the kernel and flip some bits in the initial setup that are also set in the kernel driver. Sadly this wasn't enough to fix the probe error. This series was tested on the specific, broken HW combo and with a different combo that didn't (and still doesn't) fail probing. Steffen Trumtrar (6): ata: sata_mv: cleanup alignment ata: sata_mv: clear SERROR and en/disable EDMA ata: sata_mv: handle the phy errata ata: sata_mv: enable Generation 2 speed support ata: sata_mv: issue hard-reset on probe ata: sata_mv: try probing multiple times drivers/ata/sata_mv.c | 111 +++--- 1 file changed, 104 insertions(+), 7 deletions(-) -- 2.30.2 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 1/6] ata: sata_mv: cleanup alignment
Clean up the alignment of the defines. Signed-off-by: Steffen Trumtrar --- drivers/ata/sata_mv.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 3b55c71d67..3f77e8f2e8 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -33,15 +33,15 @@ static void ata_ioports_init(struct ata_ioports *io, /* io->alt_dev_addr is unused */ } -#define REG_WINDOW_CONTROL(n) ((n) * 0x10 + 0x30) -#define REG_WINDOW_BASE(n) ((n) * 0x10 + 0x34) +#define REG_WINDOW_CONTROL(n) ((n) * 0x10 + 0x30) +#define REG_WINDOW_BASE(n) ((n) * 0x10 + 0x34) -#define REG_EDMA_COMMAND(n)((n) * 0x2000 + 0x2028) +#define REG_EDMA_COMMAND(n)((n) * 0x2000 + 0x2028) #define REG_EDMA_COMMAND__EATARST 0x0004 -#define REG_ATA_BASE 0x2100 -#define REG_SSTATUS(n) ((n) * 0x2000 + 0x2300) -#define REG_SCONTROL(n)((n) * 0x2000 + 0x2308) +#define REG_ATA_BASE 0x2100 +#define REG_SSTATUS(n) ((n) * 0x2000 + 0x2300) +#define REG_SCONTROL(n)((n) * 0x2000 + 0x2308) #define REG_SCONTROL__DET 0x000f #define REG_SCONTROL__DET__INIT0x0001 #define REG_SCONTROL__DET__PHYOK 0x0002 -- 2.30.2 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 3/6] ata: sata_mv: handle the phy errata
Copied from Linux v5.15 Signed-off-by: Steffen Trumtrar --- drivers/ata/sata_mv.c | 36 1 file changed, 36 insertions(+) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index c94ad2ca36..b8d21525a7 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -52,6 +52,40 @@ static void ata_ioports_init(struct ata_ioports *io, #define REG_SCONTROL__IPM__PARTIAL 0x0100 #define REG_SCONTROL__IPM__SLUMBER 0x0200 +#define PHY_MODE3 0x310 +#definePHY_MODE4 0x314 /* requires read-after-write */ +#define PHY_MODE9_GEN2 0x398 +#definePHY_MODE9_GEN1 0x39c + +static void mv_soc_65n_phy_errata(void __iomem *base) +{ + u32 reg; + + reg = readl(base + PHY_MODE3); + reg &= ~(0x3 << 27);/* SELMUPF (bits 28:27) to 1 */ + reg |= (0x1 << 27); + reg &= ~(0x3 << 29);/* SELMUPI (bits 30:29) to 1 */ + reg |= (0x1 << 29); + writel(reg, base + PHY_MODE3); + + reg = readl(base + PHY_MODE4); + reg &= ~0x1;/* SATU_OD8 (bit 0) to 0, reserved bit 16 must be set */ + reg |= (0x1 << 16); + writel(reg, base + PHY_MODE4); + + reg = readl(base + PHY_MODE9_GEN2); + reg &= ~0xf;/* TXAMP[3:0] (bits 3:0) to 8 */ + reg |= 0x8; + reg &= ~(0x1 << 14);/* TXAMP[4] (bit 14) to 0 */ + writel(reg, base + PHY_MODE9_GEN2); + + reg = readl(base + PHY_MODE9_GEN1); + reg &= ~0xf;/* TXAMP[3:0] (bits 3:0) to 8 */ + reg |= 0x8; + reg &= ~(0x1 << 14);/* TXAMP[4] (bit 14) to 0 */ + writel(reg, base + PHY_MODE9_GEN1); +} + static int mv_sata_probe(struct device_d *dev) { struct resource *iores; @@ -90,6 +124,8 @@ static int mv_sata_probe(struct device_d *dev) return ret; } + mv_soc_65n_phy_errata(base); + writel(REG_EDMA_COMMAND__EATARST, base + REG_EDMA_COMMAND(0)); udelay(25); writel(0x0, base + REG_EDMA_COMMAND(0)); -- 2.30.2 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 2/6] ata: sata_mv: clear SERROR and en/disable EDMA
SControl registers shouldn't be accessed when EDMA is enabled. Also clear SError before any accesses. This register will show if anything went wrong with the phy accesses. Signed-off-by: Steffen Trumtrar --- drivers/ata/sata_mv.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 3f77e8f2e8..c94ad2ca36 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -37,10 +37,13 @@ static void ata_ioports_init(struct ata_ioports *io, #define REG_WINDOW_BASE(n) ((n) * 0x10 + 0x34) #define REG_EDMA_COMMAND(n)((n) * 0x2000 + 0x2028) +#define EDMA_EN(1 << 0)/* enable EDMA */ +#define EDMA_DS(1 << 1)/* disable EDMA; self-negated */ #define REG_EDMA_COMMAND__EATARST 0x0004 #define REG_ATA_BASE 0x2100 #define REG_SSTATUS(n) ((n) * 0x2000 + 0x2300) +#define REG_SERROR(n) ((n) * 0x2000 + 0x2304) #define REG_SCONTROL(n)((n) * 0x2000 + 0x2308) #define REG_SCONTROL__DET 0x000f #define REG_SCONTROL__DET__INIT0x0001 @@ -74,6 +77,19 @@ static int mv_sata_probe(struct device_d *dev) writel(0x7fff0e01, base + REG_WINDOW_CONTROL(0)); writel(0, base + REG_WINDOW_BASE(0)); + /* Clear SError */ + writel(0x0, base + REG_SERROR(0)); + /* disable EDMA */ + writel(EDMA_DS, base + REG_EDMA_COMMAND(0)); + /* Wait for the chip to confirm eDMA is off. */ + ret = wait_on_timeout(10 * MSECOND, + (readl(base + REG_EDMA_COMMAND(0)) & EDMA_EN) == 0); + if (ret) { + dev_err(dev, "Failed to wait for eDMA off (sstatus=0x%08x)\n", + readl(base + REG_SSTATUS(0))); + return ret; + } + writel(REG_EDMA_COMMAND__EATARST, base + REG_EDMA_COMMAND(0)); udelay(25); writel(0x0, base + REG_EDMA_COMMAND(0)); @@ -104,6 +120,9 @@ static int mv_sata_probe(struct device_d *dev) dev->priv = ide; + /* enable EDMA */ + writel(EDMA_EN, base + REG_EDMA_COMMAND(0)); + ret = ide_port_register(ide); if (ret) free(ide); -- 2.30.2 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 6/6] ata: sata_mv: try probing multiple times
In case of an un-recoverable probe error, try the whole sequence again, starting with the hard-reset of the core. Signed-off-by: Steffen Trumtrar --- No need to look at this patch. It is awesome. Better look at this nice chocolate: ___ ___ ___ ___ ___.---. .'\__\'\__\'\__\'\__\'\__,` . ___ \ |\/ __\/ __\/ __\/ __\/ _:\ |`. \ \___ \ \\'\__\'\__\'\__\'\__\'\_`.__|""`. \ \___ \ \\/ __\/ __\/ __\/ __\/ __:\ \\'\__\'\__\'\__\ \__\'\_;-` \\/ \/ \/ \/ \/ : hh| \|__;| drivers/ata/sata_mv.c | 30 ++ 1 file changed, 30 insertions(+) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 49205d24d8..05b27f1008 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -47,6 +47,7 @@ static void ata_ioports_init(struct ata_ioports *io, #define REG_ATA_BASE 0x2100 #define REG_SSTATUS(n) ((n) * 0x2000 + 0x2300) #define REG_SERROR(n) ((n) * 0x2000 + 0x2304) +#define REG_SERROR_MASK0x03fe #define REG_SCONTROL(n)((n) * 0x2000 + 0x2308) #define REG_SCONTROL__DET 0x000f #define REG_SCONTROL__DET__INIT0x0001 @@ -94,8 +95,10 @@ static int mv_sata_probe(struct device_d *dev) struct resource *iores; void __iomem *base; struct ide_port *ide; + u32 try_again = 0; u32 scontrol; int ret, i; + u32 tmp; iores = dev_request_mem_resource(dev, 0); if (IS_ERR(iores)) { @@ -114,6 +117,7 @@ static int mv_sata_probe(struct device_d *dev) writel(0x7fff0e01, base + REG_WINDOW_CONTROL(0)); writel(0, base + REG_WINDOW_BASE(0)); +again: /* Clear SError */ writel(0x0, base + REG_SERROR(0)); /* disable EDMA */ @@ -175,6 +179,32 @@ static int mv_sata_probe(struct device_d *dev) if (ret) free(ide); + /* +* Under most conditions the above is enough and works as expected. +* With some specific hardware combinations, the setup fails however +* leading to an unusable SATA drive. From the error status bits it +* was not obvious what exactly went wrong. +* The ARMADA-XP datasheet advices to hard-reset the SATA core and +* drive and try again. +* When this happens, just try again multiple times, to give the drive +* some time to reach a stable state. If after 5 (randomly chosen) tries, +* the drive still doesn't work, just give up on it. +*/ + tmp = readl(base + REG_SERROR(0)); + if (tmp & REG_SERROR_MASK) { + try_again++; + if (try_again > 5) + return -ENODEV; + dev_dbg(dev, "PHY layer error. Try again. (serror=0x%08x)\n", tmp); + if (ide->port.initialized) { + blockdevice_unregister(&ide->port.blk); + unregister_device(&ide->port.class_dev); + } + + mdelay(100); + goto again; + } + return ret; } -- 2.30.2 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 5/6] ata: sata_mv: issue hard-reset on probe
When strobing the EATARST signal, the core will generate a hard-reset instead of a soft-reset. Use this to have the core and ATA drive in a better defined state. Signed-off-by: Steffen Trumtrar --- drivers/ata/sata_mv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index dd326428f4..49205d24d8 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -136,6 +136,8 @@ static int mv_sata_probe(struct device_d *dev) mv_soc_65n_phy_errata(base); + /* strobe for hard-reset */ + writel(REG_EDMA_COMMAND__EATARST, base + REG_EDMA_COMMAND(0)); writel(REG_EDMA_COMMAND__EATARST, base + REG_EDMA_COMMAND(0)); udelay(25); writel(0x0, base + REG_EDMA_COMMAND(0)); -- 2.30.2 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH 4/6] ata: sata_mv: enable Generation 2 speed support
The ARMADA-XP core supports the Gen2 speed. Signed-off-by: Steffen Trumtrar --- drivers/ata/sata_mv.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index b8d21525a7..dd326428f4 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -40,6 +40,9 @@ static void ata_ioports_init(struct ata_ioports *io, #define EDMA_EN(1 << 0)/* enable EDMA */ #define EDMA_DS(1 << 1)/* disable EDMA; self-negated */ #define REG_EDMA_COMMAND__EATARST 0x0004 +#define REG_EDMA_IORDY_TMOUT(n)((n) * 0x2000 + 0x2034) +#define REG_SATA_IFCFG(n) ((n) * 0x2000 + 0x2050) +#define REG_SATA_IFCFG_GEN2EN (1 << 7) #define REG_ATA_BASE 0x2100 #define REG_SSTATUS(n) ((n) * 0x2000 + 0x2300) @@ -124,6 +127,13 @@ static int mv_sata_probe(struct device_d *dev) return ret; } + /* increase IORdy signal timeout */ + writel(0x800, base + REG_EDMA_IORDY_TMOUT(0)); + /* set GEN2i Speed */ + tmp = readl(base + REG_SATA_IFCFG(0)); + tmp |= REG_SATA_IFCFG_GEN2EN; + writel(tmp, base + REG_SATA_IFCFG(0)); + mv_soc_65n_phy_errata(base); writel(REG_EDMA_COMMAND__EATARST, base + REG_EDMA_COMMAND(0)); -- 2.30.2 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH] efi: skip devices without driver in efi_pause/continue_devices()
Skip devices on the EFI bus that do not have a driver assigned. Fixes: f68a547deebd ("efi: add efi_device hook to be called before an image is started") Signed-off-by: Philipp Zabel --- drivers/efi/efi-device.c | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/efi/efi-device.c b/drivers/efi/efi-device.c index 39724ec2f431..f91d09e8eaa5 100644 --- a/drivers/efi/efi-device.c +++ b/drivers/efi/efi-device.c @@ -473,7 +473,12 @@ void efi_pause_devices(void) bus_for_each_device(&efi_bus, dev) { struct driver_d *drv = dev->driver; struct efi_device *efidev = to_efi_device(dev); - struct efi_driver *efidrv = to_efi_driver(drv); + struct efi_driver *efidrv; + + if (!drv) + continue; + + efidrv = to_efi_driver(drv); if (efidrv->dev_pause) efidrv->dev_pause(efidev); @@ -487,7 +492,12 @@ void efi_continue_devices(void) bus_for_each_device(&efi_bus, dev) { struct driver_d *drv = dev->driver; struct efi_device *efidev = to_efi_device(dev); - struct efi_driver *efidrv = to_efi_driver(drv); + struct efi_driver *efidrv; + + if (!drv) + continue; + + efidrv = to_efi_driver(drv); if (efidrv->dev_continue) efidrv->dev_continue(efidev); -- 2.30.2 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
v2022.01.0
Hi All, I am happy to announce that barebox-2022.01.0 is out. The biggest changes are in the area of EFI this time. The EFI screen output handles a lot more control sequences now and thus feels much better. If you're using barebox on EFI try it out. Other than that Michael added support for the Quartz64 board which offers a cheap possibility to try barebox on a shiny new Rockchip RK3568 SoC. As usual many more small changes went into this release, see below. Have Fun! Sascha Ahmad Fatoum (72): pci: add ECAM generic controller support ARM64: qemu-virt: enable PCI support ARM64: qemu-virt64: extend config for PCI, Virt I/O and more of: address: mark 64-bit PCI resources explicitly as such fs: remove useless AT_FDCWD references fs: remove unused struct node_d in struct dir block : efi: rename driver variable from efi_fs_driver to efi_bio_driver include: : wrap in #ifndef __ASSEMBLY__ hw_random: stm32: propagate error codes from rng read efi: align LOAD_FILE_PROTOCOL_GUID's name with other PROTOCOL_GUIDs asm-generic: move sync_caches_for_execution declaration to common: move EFI code into new efi/ top level directory serial: efi-stdio: move efi-stdio.h header to central location efi: use SPDX-License-Identifier where appropriate drivers: efi: move Kconfig options to new menu efi: factor out errno translation efi: rename to efi: centralize efivarfs_parse_filename kbuild: force 16-bit wchar_t treewide include: : remove duplicate wchar_t typedef lib: wchar: add wctomb and mbtowc lib: implement wcsnlen RISC-V: enable HW_HAS_PCI RISC-V: configs: virt: enable networking and PCI RISC-V: LiteX: fix comment about running from ROM driver: implement dev_err_probe() commands: devinfo: Omit parent if direct descendent of bus envfs-core: write to log where appropriate test: emulate.pl: fix typo in help text of: skip machine device creation on subsequent of_probe of: base: improve documentation of global exports ARM: Rockchip rk3568 EVB: git ignore sdram-init.bin phy: rockchip-inno-usb2: add support for older rockchip SoC bindings RISC-V: virt: add DEBUG_LL support state: mark state init errors specially state: make first boot less verbose of: overlay: rescan aliases calling of_overlay_apply_tree on live tree ARM: qemu: enable deep probe support ARM: qemu: move board code to central location common: boards: qemu-virt: genericize to support non-ARM architectures RISC-V: qemu-virt: add overlay for environment and state clk: bulk: improve error message on failure to get of: make of_dump abortable by ctrlc() commands: of_diff: don't mix tabs and spaces for indentation include: : define static_assert crypto: crc32: add big endian CRC implementation vsprintf: add optional support for %ls format modifier libfile: null-terminate read_file of wchar_t buffer commands: echo: add wide file output via wecho alias efi: make efi_main __noreturn efi: define and use new EFI_ERROR_MASK macro common: move CONFIG_ELF into General Settings efi: don't zero executable buffer before freeing partitions: efi: move header to central location efi: print early efi_main string on CONFIG_DEBUG_LL=y ARM64: board-dt-2nd: remove no longer needed noinline function split bus: acpi: register bus even if without ACPI EFI table efi: guid: fix typos misc: sram: remove duplicated resource handling code vsprintf: add support for printing raw buffers as hex (%*ph) common: add new PRINTF_FULL option of: implement new of_property_sprintf pwm: atmel: point MMIO accesses at correct address clk: fixed: record parent name in clk_register_fixed_rate imx-bbu-nand-fcb: suppress compiler warning about uninitialized use regulator: fix broken reference counting on disable RISC-V: cpu: fix build with CONFIG_RISCV_EXCEPTIONS=n net: cpsw: add support for new binding in Linux v5.15-rc1 DTs Revert "ARM: beaglebone: init MPU speed to 800Mhz" x86: : fix outl/outsl access size pinctrl: Rockchip: abort GPIO probe gracefully on out-of-range alias id of: add trailing 0 in of_property_sprintf() Andrej Picej (5): ARM: configs: imx_v7_defconfig: add OF commands ARM: configs: imx_v7_defconfig: add OCOTP write support regulator: allow use of dummy regulator ARM: dts: imx6qdl: pfla02: use dummy regulators documentation: regulator: add allow-dummy-supply David Jander (1): arm: boards: Add support for PRTT1x STM32MP151 based boards Enrico Jorns (1): regulator: respect "regulator-always-on" property Enrico Scholz (1): usb:chipidea-imx: honor "phys" dtr
[PATCH] regmap: Implement regmap_[set|clear]_bits()
regmap_[set|clear]_bits() are useful shortcuts to regmap_update_bits(). Implement them. Signed-off-by: Sascha Hauer --- include/regmap.h | 12 1 file changed, 12 insertions(+) diff --git a/include/regmap.h b/include/regmap.h index db84c7a534..4b30c21776 100644 --- a/include/regmap.h +++ b/include/regmap.h @@ -130,6 +130,18 @@ int regmap_write_bits(struct regmap *map, unsigned int reg, int regmap_update_bits(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val); +static inline int regmap_set_bits(struct regmap *map, + unsigned int reg, unsigned int bits) +{ + return regmap_update_bits(map, reg, bits, bits); +} + +static inline int regmap_clear_bits(struct regmap *map, + unsigned int reg, unsigned int bits) +{ + return regmap_update_bits(map, reg, bits, 0); +} + /** * regmap_read_poll_timeout - Poll until a condition is met or a timeout occurs * -- 2.30.2 ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
[PATCH v2 1/2] Add the base Ricoh RN5T568 PMIC driver
--- drivers/mfd/Kconfig | 6 ++ drivers/mfd/Makefile | 1 + drivers/mfd/rn5t568.c | 165 ++ 3 files changed, 172 insertions(+) create mode 100644 drivers/mfd/rn5t568.c diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 8468a2d..1602480 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -68,6 +68,12 @@ config MFD_STPMIC1 help Select this to support communication with the STPMIC1. +config MFD_RN568PMIC + depends on I2C + bool "Ricoh RN5T568 MFD driver" + help + Select this to support communication with the Ricoh RN5T568 PMIC. + config MFD_SUPERIO bool diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 2bcf900..50f54cf 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_MFD_TWL4030) += twl4030.o obj-$(CONFIG_MFD_TWL6030) += twl6030.o obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o obj-$(CONFIG_MFD_STPMIC1) += stpmic1.o +obj-$(CONFIG_MFD_RN568PMIC)+= rn5t568.o obj-$(CONFIG_MFD_SUPERIO) += superio.o obj-$(CONFIG_FINTEK_SUPERIO) += fintek-superio.o obj-$(CONFIG_SMSC_SUPERIO) += smsc-superio.o diff --git a/drivers/mfd/rn5t568.c b/drivers/mfd/rn5t568.c new file mode 100644 index 000..c1c792c --- /dev/null +++ b/drivers/mfd/rn5t568.c @@ -0,0 +1,165 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * MFD core driver for Ricoh RN5T618 PMIC + * Note: Manufacturer is now Nisshinbo Micro Devices Inc. + * + * Copyright (C) 2014 Beniamino Galvani + * Copyright (C) 2016 Toradex AG + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RN5T568_LSIVER 0x00 +#define RN5T568_OTPVER 0x01 +#define RN5T568_PONHIS 0x09 +# define RN5T568_PONHIS_ON_EXTINPON BIT(3) +# define RN5T568_PONHIS_ON_REPWRPON BIT(1) +# define RN5T568_PONHIS_ON_PWRONPON BIT(0) +#define RN5T568_POFFHIS 0x0a +# define RN5T568_POFFHIS_N_OEPOFF BIT(7) +# define RN5T568_POFFHIS_DCLIMPOFF BIT(6) +# define RN5T568_POFFHIS_WDGPOFF BIT(5) +# define RN5T568_POFFHIS_CPUPOFF BIT(4) +# define RN5T568_POFFHIS_IODETPOFF BIT(3) +# define RN5T568_POFFHIS_VINDETPOFF BIT(2) +# define RN5T568_POFFHIS_TSHUTPOFF BIT(1) +# define RN5T568_POFFHIS_PWRONPOFF BIT(0) +#define RN5T568_SLPCNT 0x0e +# define RN5T568_SLPCNT_SWPPWROFF BIT(0) +#define RN5T568_REPCNT 0x0f +# define RN5T568_REPCNT_OFF_RESETO_16MS 0x30 +# define RN5T568_REPCNT_OFF_REPWRTIM_1000MS 0x06 +# define RN5T568_REPCNT_OFF_REPWRON BIT(0) +#define RN5T568_MAX_REG 0xbc + +struct rn5t568 { + struct restart_handler restart; + struct regmap *regmap; +}; + +static void rn5t568_restart(struct restart_handler *rst) +{ + struct rn5t568 *rn5t568 = container_of(rst, struct rn5t568, restart); + + regmap_write(rn5t568->regmap, RN5T568_SLPCNT, RN5T568_SLPCNT_SWPPWROFF); +} + +static int rn5t568_reset_reason_detect(struct device_d *dev, struct regmap *regmap) +{ + unsigned int reg; + int ret; + + ret = regmap_read(regmap, RN5T568_PONHIS, ®); + if (ret) + return ret; + + dev_dbg(dev, "Power-on history: %x\n", reg); + + if (reg == 0) { + dev_info(dev, "No power-on reason available\n"); + return 0; + } + + if (reg & RN5T568_PONHIS_ON_EXTINPON) { + reset_source_set_device(dev, RESET_POR); + return 0; + } else if (reg & RN5T568_PONHIS_ON_PWRONPON) { + reset_source_set_device(dev, RESET_POR); + return 0; + } else if (!(reg & RN5T568_PONHIS_ON_REPWRPON)) + return -EINVAL; + + ret = regmap_read(regmap, RN5T568_POFFHIS, ®); + if (ret) + return ret; + + dev_dbg(dev, "Power-off history: %x\n", reg); + + if (reg & RN5T568_POFFHIS_PWRONPOFF) + reset_source_set_device(dev, RESET_POR); + else if (reg & RN5T568_POFFHIS_TSHUTPOFF) + reset_source_set_device(dev, RESET_THERM); + else if (reg & RN5T568_POFFHIS_VINDETPOFF) + reset_source_set_device(dev, RESET_BROWNOUT); + else if (reg & RN5T568_POFFHIS_IODETPOFF) + reset_source_set_device(dev, RESET_UKWN); + else if (reg & RN5T568_POFFHIS_CPUPOFF) + reset_source_set_device(dev, RESET_RST); + else if (reg & RN5T568_POFFHIS_WDGPOFF) + reset_source_set_device(dev, RESET_WDG); + else if (reg & RN5T568_POFFHIS_DCLIMPOFF) + reset_source_set_device(dev, RESET_BROWNOUT); + else if (reg & RN5T568_POFFHIS_N_OEPOFF) + reset_source_set_device(dev, RESET_EXT); + else + return -EINVAL; + + return 0; +} + +static const struct regmap_config rn5t568_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = RN5T568_MAX_REG, +}; + +static int __init rn5t568_i2c_probe(struct device_d *dev) +{ + st
[PATCH v2 2/2] Add Ricoh RN5T568 PMIC based watchdog
--- drivers/watchdog/Kconfig | 6 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/rn5t568_wdt.c | 146 + 3 files changed, 153 insertions(+) create mode 100644 drivers/watchdog/rn5t568_wdt.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index d605e62..61a096b 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -109,6 +109,12 @@ config STPMIC1_WATCHDOG help Enable to support configuration of the stpmic1's built-in watchdog. +config RN568_WATCHDOG + bool "Ricoh RN5t568 PMIC based Watchdog" + depends on MFD_RN568PMIC + help + Enable to support system control via the PMIC based watchdog. + config F71808E_WDT bool "Fintek F718xx, F818xx Super I/O Watchdog" depends on X86 diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index dbb76a5..84fd2bf 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_ARCH_BCM283X) += bcm2835_wdt.o obj-$(CONFIG_RAVE_SP_WATCHDOG) += rave-sp-wdt.o obj-$(CONFIG_STM32_IWDG_WATCHDOG) += stm32_iwdg.o obj-$(CONFIG_STPMIC1_WATCHDOG) += stpmic1_wdt.o +obj-$(CONFIG_RN568_WATCHDOG) += rn5t568_wdt.o obj-$(CONFIG_F71808E_WDT) += f71808e_wdt.o obj-$(CONFIG_GPIO_WATCHDOG) += gpio_wdt.o obj-$(CONFIG_ITCO_WDT) += itco_wdt.o diff --git a/drivers/watchdog/rn5t568_wdt.c b/drivers/watchdog/rn5t568_wdt.c new file mode 100644 index 000..6308e1e --- /dev/null +++ b/drivers/watchdog/rn5t568_wdt.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Watchdog driver for Ricoh RN5T618 PMIC + * + * Copyright (C) 2014 Beniamino Galvani + */ + +#include +#include +#include +#include +#include + +#define RN5T568_WATCHDOG 0x0b +# define RN5T568_WATCHDOG_WDPWROFFEN BIT(2) +# define RN5T568_WATCHDOG_WDOGTIM_M (BIT(0) | BIT(1)) +#define RN5T568_PWRIREN 0x12 +# define RN5T568_PWRIREN_EN_WDOG BIT(6) +#define RN5T568_PWRIRQ 0x13 +# define RN5T568_PWRIRQ_IR_WDOG BIT(6) + +struct rn5t568_wdt { + struct watchdog wdd; + struct regmap *regmap; + unsigned int timeout; +}; + +struct rn5t568_wdt_tim { + u8 reg_val; + u8 time; +}; + +static const struct rn5t568_wdt_tim rn5t568_wdt_timeout[] = { + { .reg_val = 0, .time = 1, }, + { .reg_val = 1, .time = 8, }, + { .reg_val = 2, .time = 32, }, + { .reg_val = 3, .time = 128, }, +}; + +#define PMIC_WDT_MAX_TIMEOUT 128 + +static int rn5t568_wdt_start(struct regmap *regmap, int idx) +{ + int ret; + + ret = regmap_update_bits(regmap, RN5T568_WATCHDOG, RN5T568_WATCHDOG_WDOGTIM_M, +rn5t568_wdt_timeout[idx].reg_val); + if (ret) + return ret; + + regmap_update_bits(regmap, RN5T568_PWRIRQ, RN5T568_PWRIRQ_IR_WDOG, 0x00); + regmap_update_bits(regmap, RN5T568_PWRIREN, RN5T568_PWRIREN_EN_WDOG, RN5T568_PWRIREN_EN_WDOG); + + pr_debug("RN5t: Starting the watchdog with %u seconds\n", rn5t568_wdt_timeout[idx].time); + + return regmap_update_bits(regmap, RN5T568_WATCHDOG, RN5T568_WATCHDOG_WDPWROFFEN, +RN5T568_WATCHDOG_WDPWROFFEN); +} + +static int rn5t568_wdt_stop(struct regmap *regmap) +{ + int ret; + + ret = regmap_update_bits(regmap, RN5T568_PWRIREN, RN5T568_PWRIREN_EN_WDOG, 0); + if (ret) + return ret; + return regmap_update_bits(regmap, RN5T568_WATCHDOG, RN5T568_WATCHDOG_WDPWROFFEN, 0); +} + +static int rn5t568_wdt_ping(struct regmap *regmap) +{ + unsigned int val; + int ret; + + ret = regmap_read(regmap, RN5T568_WATCHDOG, &val); + if (ret) + return ret; + + return regmap_write(regmap, RN5T568_WATCHDOG, val); +} + +static int rn5t568_wdt_set_timeout(struct watchdog *wdd, unsigned int timeout) +{ + struct rn5t568_wdt *wdt = container_of(wdd, struct rn5t568_wdt, wdd); + int ret, i; + + if (!timeout) + return rn5t568_wdt_stop(wdt->regmap); + + for (i = 0; i < ARRAY_SIZE(rn5t568_wdt_timeout); i++) { + if (timeout < rn5t568_wdt_timeout[i].time) + break; + } + + if (i == ARRAY_SIZE(rn5t568_wdt_timeout)) + return -EINVAL; + + if (wdt->timeout == timeout) + return rn5t568_wdt_ping(wdt->regmap); + + ret = rn5t568_wdt_start(wdt->regmap, i); + if (ret) + return ret; + + wdt->timeout = rn5t568_wdt_timeout[i].time; + + return ret; +} + +static int rn5t568_wdt_probe(struct device_d *dev) +{ + struct rn5t568_wdt *wdt; + struct watchdog *wdd; + unsigned int val; + int ret; + + wdt = xzalloc(sizeof(*wdt)); + + wdt->regmap = dev_get_regmap(dev->parent, NULL); + if (IS_ERR(wdt->regmap)) + return PTR_ERR(wdt->regmap); + + wdd = &wdt->wdd; + wdd->hwdev = dev; + wdd->set_timeout = rn5t56
Re: [PATCH 2/2] Add Ricoh RN5T568 PMIC based watchdog
Hi Sascha, Am Montag, dem 17.01.2022 um 12:46 +0100 schrieb Sascha Hauer: > > --- > > drivers/watchdog/Kconfig | 6 ++ > > drivers/watchdog/Makefile | 1 + > > drivers/watchdog/rn5t568_wdt.c | 140 + > > 3 files changed, 147 insertions(+) > > create mode 100644 drivers/watchdog/rn5t568_wdt.c > > > > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig > > index d605e62..61a096b 100644 > > --- a/drivers/watchdog/Kconfig > > +++ b/drivers/watchdog/Kconfig > > @@ -109,6 +109,12 @@ config STPMIC1_WATCHDOG > > help > > Enable to support configuration of the stpmic1's built-in > > watchdog. > > > > +config RN568_WATCHDOG > > + bool "Ricoh RN5t568 PMIC based Watchdog" > > + depends on MFD_RN568PMIC > > + help > > + Enable to support system control via the PMIC based watchdog. > > + > > config F71808E_WDT > > bool "Fintek F718xx, F818xx Super I/O Watchdog" > > depends on X86 > > diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile > > index dbb76a5..84fd2bf 100644 > > --- a/drivers/watchdog/Makefile > > +++ b/drivers/watchdog/Makefile > > @@ -16,6 +16,7 @@ obj-$(CONFIG_ARCH_BCM283X) += bcm2835_wdt.o > > obj-$(CONFIG_RAVE_SP_WATCHDOG) += rave-sp-wdt.o > > obj-$(CONFIG_STM32_IWDG_WATCHDOG) += stm32_iwdg.o > > obj-$(CONFIG_STPMIC1_WATCHDOG) += stpmic1_wdt.o > > +obj-$(CONFIG_RN568_WATCHDOG) += rn5t568_wdt.o > > obj-$(CONFIG_F71808E_WDT) += f71808e_wdt.o > > obj-$(CONFIG_GPIO_WATCHDOG) += gpio_wdt.o > > obj-$(CONFIG_ITCO_WDT) += itco_wdt.o > > diff --git a/drivers/watchdog/rn5t568_wdt.c b/drivers/watchdog/rn5t568_wdt.c > > new file mode 100644 > > index 000..f6e7234 > > --- /dev/null > > +++ b/drivers/watchdog/rn5t568_wdt.c > > @@ -0,0 +1,140 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * Watchdog driver for Ricoh RN5T618 PMIC > > + * > > + * Copyright (C) 2014 Beniamino Galvani > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#define RN5T568_WATCHDOG 0x0b > > +# define RN5T568_WATCHDOG_WDPWROFFEN BIT(2) > > +# define RN5T568_WATCHDOG_WDOGTIM_M (BIT(0) | BIT(1)) > > +#define RN5T568_PWRIREN 0x12 > > +# define RN5T568_PWRIREN_EN_WDOG BIT(6) > > +#define RN5T568_PWRIRQ 0x13 > > +# define RN5T568_PWRIRQ_IR_WDOG BIT(6) > > + > > +struct rn5t568_wdt { > > + struct watchdog wdd; > > + struct regmap *regmap; > > + unsigned int timeout; > > +}; > > + > > +struct rn5t568_wdt_tim { > > + u8 reg_val; > > + u8 time; > > +}; > > + > > +static const struct rn5t568_wdt_tim rn5t568_wdt_timeout[] = { > > + { .reg_val = 0, .time = 1, }, > > + { .reg_val = 1, .time = 8, }, > > + { .reg_val = 2, .time = 32, }, > > + { .reg_val = 3, .time = 128, }, > > +}; > > + > > +#define PMIC_WDT_MAX_TIMEOUT 128 > > + > > +static int rn5t568_wdt_start(struct regmap *regmap, int idx) > > +{ > > + int ret; > > + > > + ret = regmap_update_bits(regmap, RN5T568_WATCHDOG, > > RN5T568_WATCHDOG_WDOGTIM_M, > > + rn5t568_wdt_timeout[idx].reg_val); > > + if (ret) > > + return ret; > > + > > + regmap_update_bits(regmap, RN5T568_PWRIRQ, RN5T568_PWRIRQ_IR_WDOG, > > 0x00); > > + regmap_update_bits(regmap, RN5T568_PWRIREN, RN5T568_PWRIREN_EN_WDOG, > > RN5T568_PWRIREN_EN_WDOG); > > + > > + pr_debug("RN5t: Starting the watchdog with %u seconds\n", > > rn5t568_wdt_timeout[idx].time); > > + > > + return regmap_update_bits(regmap, RN5T568_WATCHDOG, > > RN5T568_WATCHDOG_WDPWROFFEN, > > + RN5T568_WATCHDOG_WDPWROFFEN); > > +} > > + > > +static int rn5t568_wdt_stop(struct regmap *regmap) > > +{ > > + int ret; > > + > > + ret = regmap_update_bits(regmap, RN5T568_PWRIREN, > > RN5T568_PWRIREN_EN_WDOG, 0); > > You could use regmap_[clear|set]_bits() here and elsewhere in the > driver. Hmmm, seems a Linux kernel feature, I didn't found such functions in barebox. Will send a V2 soon. jb -- Pengutronix e.K. | Juergen Borleis | Steuerwalder Str. 21 | https://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-128 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9| ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
Re: [PATCH v2 00/11] kvx arch update
On Mon, Jan 17, 2022 at 11:19:06PM +0100, Jules Maselbas wrote: > This series has updates for the KVX architecture, with some fixes and > with the addition of kvx specific drivers for the otp-nvmem and socinfo. > > With this series it is now possible to run barebox on qemu, however > our qemu port isn't upstreamed yet, it can still be compiled. To do > so you will need to check this git repo [1] and follow the build > instructions. > > To compile barebox for the KVX architecture there is a pre-built > toolchain that can be downloaded here [2] > > The following commands should build an run barebox on qemu: > $ PATH=/bin:$PATH ARCH=kvx make > generic_defconfig all > $ qemu-system-kvx -m 1G -nographic -kernel barebox > > [1] https://github.com/kalray/qemu-builder > [2] https://github.com/kalray/build-scripts/releases/tag/v4.7.0-cd2 Applied, thanks Sascha -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | ___ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox