diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-18 12:08:13 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-18 12:08:13 -0700 |
| commit | 1200d84f4c0a929a0780180d25063d93773be79c (patch) | |
| tree | 27d498f910603e4f15d587aeb9384969dd9c1774 /drivers | |
| parent | 85cdaca6970028bf6f544c355c90035586836ddf (diff) | |
| parent | 1304643a1c20badbb91b86a5084dd76cb7620c05 (diff) | |
Merge tag 'powerpc-7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc updates from Madhavan Srinivasan:
- Enable Rust for ppc64le
- ppc4xx gpio driver updates
- Add power12 base enablement support
- Validate arch_compat against host compatibility mode
- Simplify bootx_scan_dt_build_struct() in powermac platform
- Implement get_direction() in cpm2
- Use cpu_relax() in ps3_create_spu()
- Add NULL guard for cause_ipi in smp_muxed_ipi_message_pass
- Fixes to handle pseries watchdogs in kdump path
- Fix missing r2 clobber in PCREL inline assembly
- Set GPIO chip parent on ppc44x
- KVM: Introduce KVM_CAP_PPC_COMPAT_CAPS and wire up ioctl
- KVM: Use generic xfer to guest work function
- Enable to run posix cpu timers in task context
- Misc fixes and cleanups
Thanks to Aditya Gupta, Alice Ryhl, Amit Machhiwal, Andrew Morton,
Anushree Mathur, Athira Rajeev, Bartosz Golaszewski, Cédric Le Goater,
Christian König, Christophe Leroy (CS GROUP), Gary Guo, Gaurav Batra,
Gautam Menghani, Gou Hao, Hari Bathini, Harsh Prateek Bora, jiazhenyuan,
Jinjie Ruan, Link Mauve, Linus Walleij, Mahesh Kumar G Mahesh
Salgaonkar, Michael Walle, Michal Suchánek, Mukesh Kumar Chaurasiya
(IBM), Nicholas Piggin, Nikhil Kumar Singh, Praveen K Pandey, Ritesh
Harjani (IBM), Rosen Penev, Saket Kumar Bhaskar, Shrikanth Hegde,
Sourabh Jain, Thorsten Blum, Vaibhav Jain, Venkat Rao Bagalkote, Vishal
Chourasia, Wentao Guan, and Yanfei Xu.
* tag 'powerpc-7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (62 commits)
powerpc/pseries/iommu: switch to Default DMA window during kdump
powerpc/configs: enable CONFIG_RAS to fix EDAC support
KVM: PPC: Document KVM_PPC_GET_COMPAT_CAPS ioctl
KVM: PPC: Book3S HV: Add support for compat CPU capabilities for KVM on PowerNV
KVM: PPC: Book3S HV: Implement compat CPU capability retrieval for KVM on PowerVM
KVM: PPC: Introduce KVM_CAP_PPC_COMPAT_CAPS and wire up ioctl
gpio: ppc44x: use dev_name() for chip label
gpio: ppc44x: fix undefined behavior in GPIO_MASK2 macro
gpio: ppc44x: drop PPC-specific IO helpers
gpio: ppc44x: Convert GPIO to generic MMIO
gpio: ppc44x: Use platform resource helper for GPIO MMIO
gpio: ppc44x: Use module platform driver helper for GPIO
gpio: ppc44x: update all 4xx to 44x
gpio: move ppc4xx gpio driver from arch/powerpc to drivers/gpio
KVM: PPC: Use min() in kvm_vm_ioctl_check_extension()
KVM: PPC: booke: Use min() in watchdog_next_timeout()
powerpc/perf: Add power12 Base Performance Monitoring support
powerpc: Add Power12 architected mode
powerpc: Add Power12 raw mode
powerpc/pseries: Limit PVR list to 16 entries for CAS negotiation
...
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpio/Kconfig | 7 | ||||
| -rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
| -rw-r--r-- | drivers/gpio/gpio-ppc44x.c | 208 | ||||
| -rw-r--r-- | drivers/watchdog/pseries-wdt.c | 53 |
4 files changed, 217 insertions, 52 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 28cf6d2e83c2..7a09e42672b4 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -593,6 +593,13 @@ config GPIO_POLARFIRE_SOC help Say yes here to support the GPIO controllers on Microchip FPGAs. +config GPIO_PPC44X + tristate "PPC44x GPIO support" + depends on 44x || COMPILE_TEST + select GPIO_GENERIC + help + Enable gpiolib support for ppc440 based boards. + config GPIO_PXA bool "PXA GPIO support" depends on ARCH_PXA || ARCH_MMP || COMPILE_TEST diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 4d0e900402fc..23aedc107cc5 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -147,6 +147,7 @@ obj-$(CONFIG_GPIO_PCIE_IDIO_24) += gpio-pcie-idio-24.o obj-$(CONFIG_GPIO_PCI_IDIO_16) += gpio-pci-idio-16.o obj-$(CONFIG_GPIO_PISOSR) += gpio-pisosr.o obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o +obj-$(CONFIG_GPIO_PPC44X) += gpio-ppc44x.o obj-$(CONFIG_GPIO_PMIC_EIC_SPRD) += gpio-pmic-eic-sprd.o obj-$(CONFIG_GPIO_POLARFIRE_SOC) += gpio-mpfs.o obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o diff --git a/drivers/gpio/gpio-ppc44x.c b/drivers/gpio/gpio-ppc44x.c new file mode 100644 index 000000000000..189667e0e1ba --- /dev/null +++ b/drivers/gpio/gpio-ppc44x.c @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * PPC44x gpio driver + * + * Copyright (c) 2008 Harris Corporation + * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix + * Copyright (c) MontaVista Software, Inc. 2008. + * + * Author: Steve Falco <sfalco@harris.com> + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/gpio/generic.h> +#include <linux/types.h> +#include <linux/slab.h> +#include <linux/platform_device.h> + +#define GPIO_MASK(gpio) (0x80000000 >> (gpio)) +#define GPIO_MASK2(gpio) (0xc0000000 >> (((gpio) % 16) * 2)) + +/* Physical GPIO register layout */ +struct ppc44x_gpio { + __be32 or; + __be32 tcr; + __be32 osrl; + __be32 osrh; + __be32 tsrl; + __be32 tsrh; + __be32 odr; + __be32 ir; + __be32 rr1; + __be32 rr2; + __be32 rr3; + __be32 reserved1; + __be32 isr1l; + __be32 isr1h; + __be32 isr2l; + __be32 isr2h; + __be32 isr3l; + __be32 isr3h; +}; + +struct ppc44x_gpio_chip { + struct gpio_generic_chip chip; + void __iomem *regs; +}; + +static inline void ppc44x_clrbits32(void __iomem *addr, u32 mask) +{ + u32 val = ioread32be(addr); + + val &= ~mask; + iowrite32be(val, addr); +} + +static inline void ppc44x_setbits32(void __iomem *addr, u32 mask) +{ + u32 val = ioread32be(addr); + + val |= mask; + iowrite32be(val, addr); +} + +/* + * GPIO LIB API implementation for GPIOs + * + * There are a maximum of 32 gpios in each gpio controller. + */ + +static inline void +__ppc44x_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct ppc44x_gpio_chip *chip = gpiochip_get_data(gc); + struct gpio_generic_chip *gen_gc = &chip->chip; + + if (val) + gen_gc->sdata |= GPIO_MASK(gpio); + else + gen_gc->sdata &= ~GPIO_MASK(gpio); + + gpio_generic_write_reg(gen_gc, gen_gc->reg_set, gen_gc->sdata); +} + +static int ppc44x_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) +{ + struct ppc44x_gpio_chip *chip = gpiochip_get_data(gc); + struct gpio_generic_chip *gen_gc = &chip->chip; + struct ppc44x_gpio __iomem *regs = chip->regs; + + guard(gpio_generic_lock_irqsave)(gen_gc); + + /* Disable open-drain function */ + ppc44x_clrbits32(®s->odr, GPIO_MASK(gpio)); + + /* Float the pin */ + ppc44x_clrbits32(®s->tcr, GPIO_MASK(gpio)); + gen_gc->sdir &= ~GPIO_MASK(gpio); + + /* Bits 0-15 use TSRL/OSRL, bits 16-31 use TSRH/OSRH */ + if (gpio < 16) { + ppc44x_clrbits32(®s->osrl, GPIO_MASK2(gpio)); + ppc44x_clrbits32(®s->tsrl, GPIO_MASK2(gpio)); + } else { + ppc44x_clrbits32(®s->osrh, GPIO_MASK2(gpio)); + ppc44x_clrbits32(®s->tsrh, GPIO_MASK2(gpio)); + } + + return 0; +} + +static int +ppc44x_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct ppc44x_gpio_chip *chip = gpiochip_get_data(gc); + struct gpio_generic_chip *gen_gc = &chip->chip; + struct ppc44x_gpio __iomem *regs = chip->regs; + + guard(gpio_generic_lock_irqsave)(gen_gc); + + /* First set initial value */ + __ppc44x_gpio_set(gc, gpio, val); + + /* Disable open-drain function */ + ppc44x_clrbits32(®s->odr, GPIO_MASK(gpio)); + + /* Drive the pin */ + ppc44x_setbits32(®s->tcr, GPIO_MASK(gpio)); + gen_gc->sdir |= GPIO_MASK(gpio); + + /* Bits 0-15 use TSRL, bits 16-31 use TSRH */ + if (gpio < 16) { + ppc44x_clrbits32(®s->osrl, GPIO_MASK2(gpio)); + ppc44x_clrbits32(®s->tsrl, GPIO_MASK2(gpio)); + } else { + ppc44x_clrbits32(®s->osrh, GPIO_MASK2(gpio)); + ppc44x_clrbits32(®s->tsrh, GPIO_MASK2(gpio)); + } + + pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); + + return 0; +} + +static int ppc44x_gpio_probe(struct platform_device *ofdev) +{ + struct device *dev = &ofdev->dev; + struct ppc44x_gpio __iomem *regs; + struct ppc44x_gpio_chip *chip; + struct gpio_generic_chip_config config; + struct gpio_chip *gc; + int ret; + + regs = devm_platform_ioremap_resource(ofdev, 0); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->regs = regs; + + config = (struct gpio_generic_chip_config) { + .dev = dev, + .sz = 4, + .dat = ®s->ir, + .set = ®s->or, + .dirout = ®s->tcr, + .flags = GPIO_GENERIC_BIG_ENDIAN | + GPIO_GENERIC_BIG_ENDIAN_BYTE_ORDER, + }; + + ret = gpio_generic_chip_init(&chip->chip, &config); + if (ret) + return ret; + + gc = &chip->chip.gc; + gc->label = dev_name(dev); + gc->parent = dev; + gc->direction_input = ppc44x_gpio_dir_in; + gc->direction_output = ppc44x_gpio_dir_out; + + return devm_gpiochip_add_data(dev, gc, chip); +} + +static const struct of_device_id ppc44x_gpio_match[] = { + { + .compatible = "ibm,ppc4xx-gpio", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, ppc44x_gpio_match); + +static struct platform_driver ppc44x_gpio_driver = { + .probe = ppc44x_gpio_probe, + .driver = { + .name = "ppc44x-gpio", + .of_match_table = ppc44x_gpio_match, + }, +}; + +MODULE_DESCRIPTION("PPC44x gpio driver"); +MODULE_LICENSE("GPL"); + +module_platform_driver(ppc44x_gpio_driver); diff --git a/drivers/watchdog/pseries-wdt.c b/drivers/watchdog/pseries-wdt.c index 48d67f7c972a..e97b943e1d3c 100644 --- a/drivers/watchdog/pseries-wdt.c +++ b/drivers/watchdog/pseries-wdt.c @@ -12,61 +12,10 @@ #include <linux/platform_device.h> #include <linux/time64.h> #include <linux/watchdog.h> +#include <asm/papr-watchdog.h> #define DRV_NAME "pseries-wdt" -/* - * H_WATCHDOG Input - * - * R4: "flags": - * - * Bits 48-55: "operation" - */ -#define PSERIES_WDTF_OP_START 0x100UL /* start timer */ -#define PSERIES_WDTF_OP_STOP 0x200UL /* stop timer */ -#define PSERIES_WDTF_OP_QUERY 0x300UL /* query timer capabilities */ - -/* - * Bits 56-63: "timeoutAction" (for "Start Watchdog" only) - */ -#define PSERIES_WDTF_ACTION_HARD_POWEROFF 0x1UL /* poweroff */ -#define PSERIES_WDTF_ACTION_HARD_RESTART 0x2UL /* restart */ -#define PSERIES_WDTF_ACTION_DUMP_RESTART 0x3UL /* dump + restart */ - -/* - * H_WATCHDOG Output - * - * R3: Return code - * - * H_SUCCESS The operation completed. - * - * H_BUSY The hypervisor is too busy; retry the operation. - * - * H_PARAMETER The given "flags" are somehow invalid. Either the - * "operation" or "timeoutAction" is invalid, or a - * reserved bit is set. - * - * H_P2 The given "watchdogNumber" is zero or exceeds the - * supported maximum value. - * - * H_P3 The given "timeoutInMs" is below the supported - * minimum value. - * - * H_NOOP The given "watchdogNumber" is already stopped. - * - * H_HARDWARE The operation failed for ineffable reasons. - * - * H_FUNCTION The H_WATCHDOG hypercall is not supported by this - * hypervisor. - * - * R4: - * - * - For the "Query Watchdog Capabilities" operation, a 64-bit - * structure: - */ -#define PSERIES_WDTQ_MIN_TIMEOUT(cap) (((cap) >> 48) & 0xffff) -#define PSERIES_WDTQ_MAX_NUMBER(cap) (((cap) >> 32) & 0xffff) - static const unsigned long pseries_wdt_action[] = { [0] = PSERIES_WDTF_ACTION_HARD_POWEROFF, [1] = PSERIES_WDTF_ACTION_HARD_RESTART, |
