Merge tag 'gpio-v5.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio
Pull GPIO updates from Linus Walleij: "This is the big slew of GPIO changes for the v5.3 kernel cycle. This is mostly incremental work this time. Three important things: - The FMC subsystem is deleted through my tree. This happens through GPIO as its demise was discussed in relation to a patch decoupling its GPIO implementation from the standard way of handling GPIO. As it turns out, that is not the only subsystem it reimplements and the authors think it is better do scratch it and start over using the proper kernel subsystems than try to polish the rust shiny. See the commit (ACKed by the maintainers) for details. - Arnd made a small devres patch that was ACKed by Greg and goes into the device core. - SPDX header change colissions may happen, because at times I've seen that quite a lot changed during the -rc:s in regards to SPDX. (It is good stuff, tglx has me convinced, and it is worth the occasional pain.) Apart from this is is nothing controversial or problematic. Summary: Core: - When a gpio_chip request GPIOs from itself, it can now fully control the line characteristics, both machine and consumer flags. This makes a lot of sense, but took some time before I figured out that this is how it has to work. - Several smallish documentation fixes. New drivers: - The PCA953x driver now supports the TI TCA9539. - The DaVinci driver now supports the K3 AM654 SoCs. Driver improvements: - Major overhaul and hardening of the OMAP driver by Russell King. - Starting to move some drivers to the new API passing irq_chip along with the gpio_chip when adding the gpio_chip instead of adding it separately. Unrelated: - Delete the FMC subsystem" * tag 'gpio-v5.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (87 commits) Revert "gpio: tegra: Clean-up debugfs initialisation" gpiolib: Use spinlock_t instead of struct spinlock gpio: stp-xway: allow compile-testing gpio: stp-xway: get rid of the #include <lantiq_soc.h> dependency gpio: stp-xway: improve module clock error handling gpio: stp-xway: simplify error handling in xway_stp_probe() gpiolib: Clarify use of non-sleeping functions gpiolib: Fix references to gpiod_[gs]et_*value_cansleep() variants gpiolib: Document new gpio_chip.init_valid_mask field Documentation: gpio: Fix reference to gpiod_get_array() gpio: pl061: drop duplicate printing of device name gpio: altera: Pass irqchip when adding gpiochip gpio: siox: Use devm_ managed gpiochip gpio: siox: Add struct device *dev helper variable gpio: siox: Pass irqchip when adding gpiochip drivers: gpio: amd-fch: make resource struct const devres: allow const resource arguments gpio: ath79: Pass irqchip when adding gpiochip gpio: tegra: Clean-up debugfs initialisation gpio: siox: Switch to IRQ_TYPE_NONE ...
This commit is contained in:
@@ -62,16 +62,12 @@ config GPIO_SYSFS
|
||||
bool "/sys/class/gpio/... (sysfs interface)"
|
||||
depends on SYSFS
|
||||
help
|
||||
Say Y here to add a sysfs interface for GPIOs.
|
||||
Say Y here to add the legacy sysfs interface for GPIOs.
|
||||
|
||||
This is mostly useful to work around omissions in a system's
|
||||
kernel support. Those are common in custom and semicustom
|
||||
hardware assembled using standard kernels with a minimum of
|
||||
custom patches. In those cases, userspace code may import
|
||||
a given GPIO from the kernel, if no kernel driver requested it.
|
||||
|
||||
Kernel drivers may also request that a particular GPIO be
|
||||
exported to userspace; this can be useful when debugging.
|
||||
This ABI is deprecated. If you want to use GPIO from userspace,
|
||||
use the character device /dev/gpiochipN with the appropriate
|
||||
ioctl() operations instead. The character device is always
|
||||
available.
|
||||
|
||||
config GPIO_GENERIC
|
||||
depends on HAS_IOMEM # Only for IOMEM drivers
|
||||
@@ -178,7 +174,7 @@ config GPIO_CLPS711X
|
||||
config GPIO_DAVINCI
|
||||
bool "TI Davinci/Keystone GPIO support"
|
||||
default y if ARCH_DAVINCI
|
||||
depends on ARM && (ARCH_DAVINCI || ARCH_KEYSTONE)
|
||||
depends on (ARM || ARM64) && (ARCH_DAVINCI || ARCH_KEYSTONE || ARCH_K3)
|
||||
help
|
||||
Say yes here to enable GPIO support for TI Davinci/Keystone SoCs.
|
||||
|
||||
@@ -493,7 +489,8 @@ config GPIO_STA2X11
|
||||
|
||||
config GPIO_STP_XWAY
|
||||
bool "XWAY STP GPIOs"
|
||||
depends on SOC_XWAY
|
||||
depends on SOC_XWAY || COMPILE_TEST
|
||||
depends on OF_GPIO
|
||||
help
|
||||
This enables support for the Serial To Parallel (STP) unit found on
|
||||
XWAY SoC. The STP allows the SoC to drive a shift registers cascade,
|
||||
@@ -602,7 +599,6 @@ config GPIO_XGENE_SB
|
||||
|
||||
config GPIO_XILINX
|
||||
tristate "Xilinx GPIO support"
|
||||
depends on OF_GPIO
|
||||
help
|
||||
Say yes here to support the Xilinx FPGA GPIO device
|
||||
|
||||
|
@@ -17,154 +17,154 @@ obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
|
||||
# directly supported by gpio-generic
|
||||
gpio-generic-$(CONFIG_GPIO_GENERIC) += gpio-mmio.o
|
||||
|
||||
obj-$(CONFIG_GPIO_104_DIO_48E) += gpio-104-dio-48e.o
|
||||
obj-$(CONFIG_GPIO_104_IDIO_16) += gpio-104-idio-16.o
|
||||
obj-$(CONFIG_GPIO_104_IDI_48) += gpio-104-idi-48.o
|
||||
obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o
|
||||
obj-$(CONFIG_GPIO_74XX_MMIO) += gpio-74xx-mmio.o
|
||||
obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o
|
||||
obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o
|
||||
obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o
|
||||
obj-$(CONFIG_GPIO_ALTERA) += gpio-altera.o
|
||||
obj-$(CONFIG_GPIO_ALTERA_A10SR) += gpio-altera-a10sr.o
|
||||
obj-$(CONFIG_GPIO_AMD_FCH) += gpio-amd-fch.o
|
||||
obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o
|
||||
obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o
|
||||
obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
|
||||
obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o
|
||||
obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o
|
||||
obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
|
||||
obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o
|
||||
obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o
|
||||
obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o
|
||||
obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
|
||||
obj-$(CONFIG_GPIO_CADENCE) += gpio-cadence.o
|
||||
obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
|
||||
obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o
|
||||
obj-$(CONFIG_GPIO_CRYSTAL_COVE) += gpio-crystalcove.o
|
||||
obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o
|
||||
obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o
|
||||
obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o
|
||||
obj-$(CONFIG_GPIO_DLN2) += gpio-dln2.o
|
||||
obj-$(CONFIG_GPIO_DWAPB) += gpio-dwapb.o
|
||||
obj-$(CONFIG_GPIO_EIC_SPRD) += gpio-eic-sprd.o
|
||||
obj-$(CONFIG_GPIO_EM) += gpio-em.o
|
||||
obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
|
||||
obj-$(CONFIG_GPIO_EXAR) += gpio-exar.o
|
||||
obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o
|
||||
obj-$(CONFIG_GPIO_FTGPIO010) += gpio-ftgpio010.o
|
||||
obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o
|
||||
obj-$(CONFIG_GPIO_GPIO_MM) += gpio-gpio-mm.o
|
||||
obj-$(CONFIG_GPIO_GRGPIO) += gpio-grgpio.o
|
||||
obj-$(CONFIG_GPIO_GW_PLD) += gpio-gw-pld.o
|
||||
obj-$(CONFIG_GPIO_HLWD) += gpio-hlwd.o
|
||||
obj-$(CONFIG_HTC_EGPIO) += gpio-htc-egpio.o
|
||||
obj-$(CONFIG_GPIO_ICH) += gpio-ich.o
|
||||
obj-$(CONFIG_GPIO_IOP) += gpio-iop.o
|
||||
obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o
|
||||
obj-$(CONFIG_GPIO_IT87) += gpio-it87.o
|
||||
obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
|
||||
obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o
|
||||
obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o
|
||||
obj-$(CONFIG_GPIO_INTEL_MID) += gpio-intel-mid.o
|
||||
obj-$(CONFIG_GPIO_LOONGSON) += gpio-loongson.o
|
||||
obj-$(CONFIG_GPIO_LP3943) += gpio-lp3943.o
|
||||
obj-$(CONFIG_GPIO_LPC18XX) += gpio-lpc18xx.o
|
||||
obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o
|
||||
obj-$(CONFIG_GPIO_LP873X) += gpio-lp873x.o
|
||||
obj-$(CONFIG_GPIO_LP87565) += gpio-lp87565.o
|
||||
obj-$(CONFIG_GPIO_LYNXPOINT) += gpio-lynxpoint.o
|
||||
obj-$(CONFIG_GPIO_MADERA) += gpio-madera.o
|
||||
obj-$(CONFIG_GPIO_MAX3191X) += gpio-max3191x.o
|
||||
obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o
|
||||
obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o
|
||||
obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o
|
||||
obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o
|
||||
obj-$(CONFIG_GPIO_MAX77620) += gpio-max77620.o
|
||||
obj-$(CONFIG_GPIO_MAX77650) += gpio-max77650.o
|
||||
obj-$(CONFIG_GPIO_MB86S7X) += gpio-mb86s7x.o
|
||||
obj-$(CONFIG_GPIO_MENZ127) += gpio-menz127.o
|
||||
obj-$(CONFIG_GPIO_MERRIFIELD) += gpio-merrifield.o
|
||||
obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
|
||||
obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
|
||||
obj-$(CONFIG_GPIO_MLXBF) += gpio-mlxbf.o
|
||||
obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o
|
||||
obj-$(CONFIG_GPIO_MM_LANTIQ) += gpio-mm-lantiq.o
|
||||
obj-$(CONFIG_GPIO_MOCKUP) += gpio-mockup.o
|
||||
obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
|
||||
obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o
|
||||
obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o
|
||||
obj-$(CONFIG_GPIO_104_DIO_48E) += gpio-104-dio-48e.o
|
||||
obj-$(CONFIG_GPIO_104_IDI_48) += gpio-104-idi-48.o
|
||||
obj-$(CONFIG_GPIO_104_IDIO_16) += gpio-104-idio-16.o
|
||||
obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o
|
||||
obj-$(CONFIG_GPIO_74XX_MMIO) += gpio-74xx-mmio.o
|
||||
obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o
|
||||
obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o
|
||||
obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o
|
||||
obj-$(CONFIG_GPIO_ALTERA_A10SR) += gpio-altera-a10sr.o
|
||||
obj-$(CONFIG_GPIO_ALTERA) += gpio-altera.o
|
||||
obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o
|
||||
obj-$(CONFIG_GPIO_AMD_FCH) += gpio-amd-fch.o
|
||||
obj-$(CONFIG_GPIO_AMDPT) += gpio-amdpt.o
|
||||
obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
|
||||
obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o
|
||||
obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o
|
||||
obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o
|
||||
obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o
|
||||
obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o
|
||||
obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
|
||||
obj-$(CONFIG_GPIO_CADENCE) += gpio-cadence.o
|
||||
obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
|
||||
obj-$(CONFIG_GPIO_SNPS_CREG) += gpio-creg-snps.o
|
||||
obj-$(CONFIG_GPIO_CRYSTAL_COVE) += gpio-crystalcove.o
|
||||
obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o
|
||||
obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o
|
||||
obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o
|
||||
obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o
|
||||
obj-$(CONFIG_GPIO_DLN2) += gpio-dln2.o
|
||||
obj-$(CONFIG_GPIO_DWAPB) += gpio-dwapb.o
|
||||
obj-$(CONFIG_GPIO_EIC_SPRD) += gpio-eic-sprd.o
|
||||
obj-$(CONFIG_GPIO_EM) += gpio-em.o
|
||||
obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
|
||||
obj-$(CONFIG_GPIO_EXAR) += gpio-exar.o
|
||||
obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o
|
||||
obj-$(CONFIG_GPIO_FTGPIO010) += gpio-ftgpio010.o
|
||||
obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o
|
||||
obj-$(CONFIG_GPIO_GPIO_MM) += gpio-gpio-mm.o
|
||||
obj-$(CONFIG_GPIO_GRGPIO) += gpio-grgpio.o
|
||||
obj-$(CONFIG_GPIO_GW_PLD) += gpio-gw-pld.o
|
||||
obj-$(CONFIG_GPIO_HLWD) += gpio-hlwd.o
|
||||
obj-$(CONFIG_HTC_EGPIO) += gpio-htc-egpio.o
|
||||
obj-$(CONFIG_GPIO_ICH) += gpio-ich.o
|
||||
obj-$(CONFIG_GPIO_INTEL_MID) += gpio-intel-mid.o
|
||||
obj-$(CONFIG_GPIO_IOP) += gpio-iop.o
|
||||
obj-$(CONFIG_GPIO_IT87) += gpio-it87.o
|
||||
obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o
|
||||
obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
|
||||
obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o
|
||||
obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o
|
||||
obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o
|
||||
obj-$(CONFIG_GPIO_LOONGSON) += gpio-loongson.o
|
||||
obj-$(CONFIG_GPIO_LP3943) += gpio-lp3943.o
|
||||
obj-$(CONFIG_GPIO_LP873X) += gpio-lp873x.o
|
||||
obj-$(CONFIG_GPIO_LP87565) += gpio-lp87565.o
|
||||
obj-$(CONFIG_GPIO_LPC18XX) += gpio-lpc18xx.o
|
||||
obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o
|
||||
obj-$(CONFIG_GPIO_LYNXPOINT) += gpio-lynxpoint.o
|
||||
obj-$(CONFIG_GPIO_MADERA) += gpio-madera.o
|
||||
obj-$(CONFIG_GPIO_MAX3191X) += gpio-max3191x.o
|
||||
obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o
|
||||
obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o
|
||||
obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o
|
||||
obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o
|
||||
obj-$(CONFIG_GPIO_MAX77620) += gpio-max77620.o
|
||||
obj-$(CONFIG_GPIO_MAX77650) += gpio-max77650.o
|
||||
obj-$(CONFIG_GPIO_MB86S7X) += gpio-mb86s7x.o
|
||||
obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
|
||||
obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
|
||||
obj-$(CONFIG_GPIO_MENZ127) += gpio-menz127.o
|
||||
obj-$(CONFIG_GPIO_MERRIFIELD) += gpio-merrifield.o
|
||||
obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o
|
||||
obj-$(CONFIG_GPIO_MLXBF) += gpio-mlxbf.o
|
||||
obj-$(CONFIG_GPIO_MM_LANTIQ) += gpio-mm-lantiq.o
|
||||
obj-$(CONFIG_GPIO_MOCKUP) += gpio-mockup.o
|
||||
obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
|
||||
obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o
|
||||
obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o
|
||||
obj-$(CONFIG_GPIO_MT7621) += gpio-mt7621.o
|
||||
obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o
|
||||
obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
|
||||
obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o
|
||||
obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o
|
||||
obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o
|
||||
obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o
|
||||
obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o
|
||||
obj-$(CONFIG_GPIO_PCH) += gpio-pch.o
|
||||
obj-$(CONFIG_GPIO_PCI_IDIO_16) += gpio-pci-idio-16.o
|
||||
obj-$(CONFIG_GPIO_PCIE_IDIO_24) += gpio-pcie-idio-24.o
|
||||
obj-$(CONFIG_GPIO_PISOSR) += gpio-pisosr.o
|
||||
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
|
||||
obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o
|
||||
obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
|
||||
obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o
|
||||
obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o
|
||||
obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o
|
||||
obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o
|
||||
obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o
|
||||
obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o
|
||||
obj-$(CONFIG_GPIO_PCH) += gpio-pch.o
|
||||
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_PMIC_EIC_SPRD) += gpio-pmic-eic-sprd.o
|
||||
obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
|
||||
obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
|
||||
obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
|
||||
obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
|
||||
obj-$(CONFIG_GPIO_REG) += gpio-reg.o
|
||||
obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
|
||||
obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
|
||||
obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
|
||||
obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
|
||||
obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
|
||||
obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
|
||||
obj-$(CONFIG_GPIO_REG) += gpio-reg.o
|
||||
obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
|
||||
obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o
|
||||
obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
|
||||
obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o
|
||||
obj-$(CONFIG_GPIO_SNPS_CREG) += gpio-creg-snps.o
|
||||
obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o
|
||||
obj-$(CONFIG_GPIO_SPEAR_SPICS) += gpio-spear-spics.o
|
||||
obj-$(CONFIG_GPIO_SPRD) += gpio-sprd.o
|
||||
obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o
|
||||
obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
|
||||
obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o
|
||||
obj-$(CONFIG_GPIO_SYSCON) += gpio-syscon.o
|
||||
obj-$(CONFIG_GPIO_TB10X) += gpio-tb10x.o
|
||||
obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o
|
||||
obj-$(CONFIG_GPIO_TEGRA) += gpio-tegra.o
|
||||
obj-$(CONFIG_GPIO_TEGRA186) += gpio-tegra186.o
|
||||
obj-$(CONFIG_GPIO_THUNDERX) += gpio-thunderx.o
|
||||
obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o
|
||||
obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o
|
||||
obj-$(CONFIG_GPIO_SIOX) += gpio-siox.o
|
||||
obj-$(CONFIG_GPIO_TPIC2810) += gpio-tpic2810.o
|
||||
obj-$(CONFIG_GPIO_TPS65086) += gpio-tps65086.o
|
||||
obj-$(CONFIG_GPIO_TPS65218) += gpio-tps65218.o
|
||||
obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o
|
||||
obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
|
||||
obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o
|
||||
obj-$(CONFIG_GPIO_TPS68470) += gpio-tps68470.o
|
||||
obj-$(CONFIG_GPIO_TQMX86) += gpio-tqmx86.o
|
||||
obj-$(CONFIG_GPIO_TS4800) += gpio-ts4800.o
|
||||
obj-$(CONFIG_GPIO_TS4900) += gpio-ts4900.o
|
||||
obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o
|
||||
obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o
|
||||
obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o
|
||||
obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o
|
||||
obj-$(CONFIG_GPIO_UNIPHIER) += gpio-uniphier.o
|
||||
obj-$(CONFIG_GPIO_VF610) += gpio-vf610.o
|
||||
obj-$(CONFIG_GPIO_VIPERBOARD) += gpio-viperboard.o
|
||||
obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o
|
||||
obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o
|
||||
obj-$(CONFIG_GPIO_WHISKEY_COVE) += gpio-wcove.o
|
||||
obj-$(CONFIG_GPIO_WINBOND) += gpio-winbond.o
|
||||
obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o
|
||||
obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o
|
||||
obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o
|
||||
obj-$(CONFIG_GPIO_WS16C48) += gpio-ws16c48.o
|
||||
obj-$(CONFIG_GPIO_XGENE) += gpio-xgene.o
|
||||
obj-$(CONFIG_GPIO_XGENE_SB) += gpio-xgene-sb.o
|
||||
obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o
|
||||
obj-$(CONFIG_GPIO_XLP) += gpio-xlp.o
|
||||
obj-$(CONFIG_GPIO_XRA1403) += gpio-xra1403.o
|
||||
obj-$(CONFIG_GPIO_XTENSA) += gpio-xtensa.o
|
||||
obj-$(CONFIG_GPIO_ZEVIO) += gpio-zevio.o
|
||||
obj-$(CONFIG_GPIO_ZYNQ) += gpio-zynq.o
|
||||
obj-$(CONFIG_GPIO_ZX) += gpio-zx.o
|
||||
obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o
|
||||
obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o
|
||||
obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
|
||||
obj-$(CONFIG_GPIO_SIOX) += gpio-siox.o
|
||||
obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o
|
||||
obj-$(CONFIG_GPIO_SPEAR_SPICS) += gpio-spear-spics.o
|
||||
obj-$(CONFIG_GPIO_SPRD) += gpio-sprd.o
|
||||
obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o
|
||||
obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
|
||||
obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o
|
||||
obj-$(CONFIG_GPIO_SYSCON) += gpio-syscon.o
|
||||
obj-$(CONFIG_GPIO_TB10X) += gpio-tb10x.o
|
||||
obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o
|
||||
obj-$(CONFIG_GPIO_TEGRA186) += gpio-tegra186.o
|
||||
obj-$(CONFIG_GPIO_TEGRA) += gpio-tegra.o
|
||||
obj-$(CONFIG_GPIO_THUNDERX) += gpio-thunderx.o
|
||||
obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o
|
||||
obj-$(CONFIG_GPIO_TPIC2810) += gpio-tpic2810.o
|
||||
obj-$(CONFIG_GPIO_TPS65086) += gpio-tps65086.o
|
||||
obj-$(CONFIG_GPIO_TPS65218) += gpio-tps65218.o
|
||||
obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o
|
||||
obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
|
||||
obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o
|
||||
obj-$(CONFIG_GPIO_TPS68470) += gpio-tps68470.o
|
||||
obj-$(CONFIG_GPIO_TQMX86) += gpio-tqmx86.o
|
||||
obj-$(CONFIG_GPIO_TS4800) += gpio-ts4800.o
|
||||
obj-$(CONFIG_GPIO_TS4900) += gpio-ts4900.o
|
||||
obj-$(CONFIG_GPIO_TS5500) += gpio-ts5500.o
|
||||
obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o
|
||||
obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o
|
||||
obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o
|
||||
obj-$(CONFIG_GPIO_UNIPHIER) += gpio-uniphier.o
|
||||
obj-$(CONFIG_GPIO_VF610) += gpio-vf610.o
|
||||
obj-$(CONFIG_GPIO_VIPERBOARD) += gpio-viperboard.o
|
||||
obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o
|
||||
obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o
|
||||
obj-$(CONFIG_GPIO_WHISKEY_COVE) += gpio-wcove.o
|
||||
obj-$(CONFIG_GPIO_WINBOND) += gpio-winbond.o
|
||||
obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o
|
||||
obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o
|
||||
obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o
|
||||
obj-$(CONFIG_GPIO_WS16C48) += gpio-ws16c48.o
|
||||
obj-$(CONFIG_GPIO_XGENE) += gpio-xgene.o
|
||||
obj-$(CONFIG_GPIO_XGENE_SB) += gpio-xgene-sb.o
|
||||
obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o
|
||||
obj-$(CONFIG_GPIO_XLP) += gpio-xlp.o
|
||||
obj-$(CONFIG_GPIO_XRA1403) += gpio-xra1403.o
|
||||
obj-$(CONFIG_GPIO_XTENSA) += gpio-xtensa.o
|
||||
obj-$(CONFIG_GPIO_ZEVIO) += gpio-zevio.o
|
||||
obj-$(CONFIG_GPIO_ZX) += gpio-zx.o
|
||||
obj-$(CONFIG_GPIO_ZYNQ) += gpio-zynq.o
|
||||
|
@@ -90,6 +90,46 @@ GPIOLIB irqchip
|
||||
The GPIOLIB irqchip is a helper irqchip for "simple cases" that should
|
||||
try to cover any generic kind of irqchip cascaded from a GPIO.
|
||||
|
||||
- Convert all the GPIOLIB_IRQCHIP users to pass an irqchip template,
|
||||
parent and flags before calling [devm_]gpiochip_add[_data]().
|
||||
Currently we set up the irqchip after setting up the gpiochip
|
||||
using gpiochip_irqchip_add() and gpiochip_set_[chained|nested]_irqchip().
|
||||
This is too complex, so convert all users over to just set up
|
||||
the irqchip before registering the gpio_chip, typical example:
|
||||
|
||||
/* Typical state container with dynamic irqchip */
|
||||
struct my_gpio {
|
||||
struct gpio_chip gc;
|
||||
struct irq_chip irq;
|
||||
};
|
||||
|
||||
int irq; /* from platform etc */
|
||||
struct my_gpio *g;
|
||||
struct gpio_irq_chip *girq
|
||||
|
||||
/* Set up the irqchip dynamically */
|
||||
g->irq.name = "my_gpio_irq";
|
||||
g->irq.irq_ack = my_gpio_ack_irq;
|
||||
g->irq.irq_mask = my_gpio_mask_irq;
|
||||
g->irq.irq_unmask = my_gpio_unmask_irq;
|
||||
g->irq.irq_set_type = my_gpio_set_irq_type;
|
||||
|
||||
/* Get a pointer to the gpio_irq_chip */
|
||||
girq = &g->gc.irq;
|
||||
girq->chip = &g->irq;
|
||||
girq->parent_handler = ftgpio_gpio_irq_handler;
|
||||
girq->num_parents = 1;
|
||||
girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
|
||||
GFP_KERNEL);
|
||||
if (!girq->parents)
|
||||
return -ENOMEM;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_bad_irq;
|
||||
girq->parents[0] = irq;
|
||||
|
||||
When this is done, we will delete the old APIs for instatiating
|
||||
GPIOLIB_IRQCHIP and simplify the code.
|
||||
|
||||
- Look over and identify any remaining easily converted drivers and
|
||||
dry-code conversions to gpiolib irqchip for maintainers to test
|
||||
|
||||
|
@@ -30,6 +30,7 @@ struct altera_gpio_chip {
|
||||
raw_spinlock_t gpio_lock;
|
||||
int interrupt_trigger;
|
||||
int mapped_irq;
|
||||
struct irq_chip irq_chip;
|
||||
};
|
||||
|
||||
static void altera_gpio_irq_unmask(struct irq_data *d)
|
||||
@@ -101,15 +102,6 @@ static unsigned int altera_gpio_irq_startup(struct irq_data *d)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip altera_irq_chip = {
|
||||
.name = "altera-gpio",
|
||||
.irq_mask = altera_gpio_irq_mask,
|
||||
.irq_unmask = altera_gpio_irq_unmask,
|
||||
.irq_set_type = altera_gpio_irq_set_type,
|
||||
.irq_startup = altera_gpio_irq_startup,
|
||||
.irq_shutdown = altera_gpio_irq_mask,
|
||||
};
|
||||
|
||||
static int altera_gpio_get(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
struct of_mm_gpio_chip *mm_gc;
|
||||
@@ -246,6 +238,7 @@ static int altera_gpio_probe(struct platform_device *pdev)
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
int reg, ret;
|
||||
struct altera_gpio_chip *altera_gc;
|
||||
struct gpio_irq_chip *girq;
|
||||
|
||||
altera_gc = devm_kzalloc(&pdev->dev, sizeof(*altera_gc), GFP_KERNEL);
|
||||
if (!altera_gc)
|
||||
@@ -273,6 +266,41 @@ static int altera_gpio_probe(struct platform_device *pdev)
|
||||
altera_gc->mmchip.gc.owner = THIS_MODULE;
|
||||
altera_gc->mmchip.gc.parent = &pdev->dev;
|
||||
|
||||
altera_gc->mapped_irq = platform_get_irq(pdev, 0);
|
||||
|
||||
if (altera_gc->mapped_irq < 0)
|
||||
goto skip_irq;
|
||||
|
||||
if (of_property_read_u32(node, "altr,interrupt-type", ®)) {
|
||||
dev_err(&pdev->dev,
|
||||
"altr,interrupt-type value not set in device tree\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
altera_gc->interrupt_trigger = reg;
|
||||
|
||||
altera_gc->irq_chip.name = "altera-gpio";
|
||||
altera_gc->irq_chip.irq_mask = altera_gpio_irq_mask;
|
||||
altera_gc->irq_chip.irq_unmask = altera_gpio_irq_unmask;
|
||||
altera_gc->irq_chip.irq_set_type = altera_gpio_irq_set_type;
|
||||
altera_gc->irq_chip.irq_startup = altera_gpio_irq_startup;
|
||||
altera_gc->irq_chip.irq_shutdown = altera_gpio_irq_mask;
|
||||
|
||||
girq = &altera_gc->mmchip.gc.irq;
|
||||
girq->chip = &altera_gc->irq_chip;
|
||||
if (altera_gc->interrupt_trigger == IRQ_TYPE_LEVEL_HIGH)
|
||||
girq->parent_handler = altera_gpio_irq_leveL_high_handler;
|
||||
else
|
||||
girq->parent_handler = altera_gpio_irq_edge_handler;
|
||||
girq->num_parents = 1;
|
||||
girq->parents = devm_kcalloc(&pdev->dev, 1, sizeof(*girq->parents),
|
||||
GFP_KERNEL);
|
||||
if (!girq->parents)
|
||||
return -ENOMEM;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_bad_irq;
|
||||
girq->parents[0] = altera_gc->mapped_irq;
|
||||
|
||||
skip_irq:
|
||||
ret = of_mm_gpiochip_add_data(node, &altera_gc->mmchip, altera_gc);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed adding memory mapped gpiochip\n");
|
||||
@@ -281,42 +309,7 @@ static int altera_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, altera_gc);
|
||||
|
||||
altera_gc->mapped_irq = platform_get_irq(pdev, 0);
|
||||
|
||||
if (altera_gc->mapped_irq < 0)
|
||||
goto skip_irq;
|
||||
|
||||
if (of_property_read_u32(node, "altr,interrupt-type", ®)) {
|
||||
ret = -EINVAL;
|
||||
dev_err(&pdev->dev,
|
||||
"altr,interrupt-type value not set in device tree\n");
|
||||
goto teardown;
|
||||
}
|
||||
altera_gc->interrupt_trigger = reg;
|
||||
|
||||
ret = gpiochip_irqchip_add(&altera_gc->mmchip.gc, &altera_irq_chip, 0,
|
||||
handle_bad_irq, IRQ_TYPE_NONE);
|
||||
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "could not add irqchip\n");
|
||||
goto teardown;
|
||||
}
|
||||
|
||||
gpiochip_set_chained_irqchip(&altera_gc->mmchip.gc,
|
||||
&altera_irq_chip,
|
||||
altera_gc->mapped_irq,
|
||||
altera_gc->interrupt_trigger == IRQ_TYPE_LEVEL_HIGH ?
|
||||
altera_gpio_irq_leveL_high_handler :
|
||||
altera_gpio_irq_edge_handler);
|
||||
|
||||
skip_irq:
|
||||
return 0;
|
||||
teardown:
|
||||
of_mm_gpiochip_remove(&altera_gc->mmchip);
|
||||
pr_err("%pOF: registration failed with status %d\n",
|
||||
node, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int altera_gpio_remove(struct platform_device *pdev)
|
||||
|
@@ -25,14 +25,13 @@
|
||||
#define AMD_FCH_GPIO_FLAG_WRITE BIT(22)
|
||||
#define AMD_FCH_GPIO_FLAG_READ BIT(16)
|
||||
|
||||
static struct resource amd_fch_gpio_iores =
|
||||
static const struct resource amd_fch_gpio_iores =
|
||||
DEFINE_RES_MEM_NAMED(
|
||||
AMD_FCH_MMIO_BASE + AMD_FCH_GPIO_BANK0_BASE,
|
||||
AMD_FCH_GPIO_SIZE,
|
||||
"amd-fch-gpio-iomem");
|
||||
|
||||
struct amd_fch_gpio_priv {
|
||||
struct platform_device *pdev;
|
||||
struct gpio_chip gc;
|
||||
void __iomem *base;
|
||||
struct amd_fch_gpio_pdata *pdata;
|
||||
@@ -153,7 +152,6 @@ static int amd_fch_gpio_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->pdata = pdata;
|
||||
priv->pdev = pdev;
|
||||
|
||||
priv->gc.owner = THIS_MODULE;
|
||||
priv->gc.parent = &pdev->dev;
|
||||
|
@@ -88,7 +88,7 @@ static int pt_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
pt_gpio->reg_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(pt_gpio->reg_base)) {
|
||||
dev_err(&pdev->dev, "Failed to map MMIO resource for PT GPIO.\n");
|
||||
dev_err(dev, "Failed to map MMIO resource for PT GPIO.\n");
|
||||
return PTR_ERR(pt_gpio->reg_base);
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ static int pt_gpio_probe(struct platform_device *pdev)
|
||||
pt_gpio->reg_base + PT_DIRECTION_REG, NULL,
|
||||
BGPIOF_READ_OUTPUT_REG_SET);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "bgpio_init failed\n");
|
||||
dev_err(dev, "bgpio_init failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -107,11 +107,11 @@ static int pt_gpio_probe(struct platform_device *pdev)
|
||||
pt_gpio->gc.free = pt_gpio_free;
|
||||
pt_gpio->gc.ngpio = PT_TOTAL_GPIO;
|
||||
#if defined(CONFIG_OF_GPIO)
|
||||
pt_gpio->gc.of_node = pdev->dev.of_node;
|
||||
pt_gpio->gc.of_node = dev->of_node;
|
||||
#endif
|
||||
ret = gpiochip_add_data(&pt_gpio->gc, pt_gpio);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register GPIO lib\n");
|
||||
dev_err(dev, "Failed to register GPIO lib\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ static int pt_gpio_probe(struct platform_device *pdev)
|
||||
writel(0, pt_gpio->reg_base + PT_SYNC_REG);
|
||||
writel(0, pt_gpio->reg_base + PT_CLOCKRATE_REG);
|
||||
|
||||
dev_dbg(&pdev->dev, "PT GPIO driver loaded\n");
|
||||
dev_dbg(dev, "PT GPIO driver loaded\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -222,14 +222,16 @@ MODULE_DEVICE_TABLE(of, ath79_gpio_of_match);
|
||||
static int ath79_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ath79_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct ath79_gpio_ctrl *ctrl;
|
||||
struct gpio_irq_chip *girq;
|
||||
struct resource *res;
|
||||
u32 ath79_gpio_count;
|
||||
bool oe_inverted;
|
||||
int err;
|
||||
|
||||
ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL);
|
||||
ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
|
||||
if (!ctrl)
|
||||
return -ENOMEM;
|
||||
platform_set_drvdata(pdev, ctrl);
|
||||
@@ -237,7 +239,7 @@ static int ath79_gpio_probe(struct platform_device *pdev)
|
||||
if (np) {
|
||||
err = of_property_read_u32(np, "ngpios", &ath79_gpio_count);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "ngpios property is not valid\n");
|
||||
dev_err(dev, "ngpios property is not valid\n");
|
||||
return err;
|
||||
}
|
||||
oe_inverted = of_device_is_compatible(np, "qca,ar9340-gpio");
|
||||
@@ -245,25 +247,24 @@ static int ath79_gpio_probe(struct platform_device *pdev)
|
||||
ath79_gpio_count = pdata->ngpios;
|
||||
oe_inverted = pdata->oe_inverted;
|
||||
} else {
|
||||
dev_err(&pdev->dev, "No DT node or platform data found\n");
|
||||
dev_err(dev, "No DT node or platform data found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ath79_gpio_count >= 32) {
|
||||
dev_err(&pdev->dev, "ngpios must be less than 32\n");
|
||||
dev_err(dev, "ngpios must be less than 32\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
ctrl->base = devm_ioremap_nocache(
|
||||
&pdev->dev, res->start, resource_size(res));
|
||||
ctrl->base = devm_ioremap_nocache(dev, res->start, resource_size(res));
|
||||
if (!ctrl->base)
|
||||
return -ENOMEM;
|
||||
|
||||
raw_spin_lock_init(&ctrl->lock);
|
||||
err = bgpio_init(&ctrl->gc, &pdev->dev, 4,
|
||||
err = bgpio_init(&ctrl->gc, dev, 4,
|
||||
ctrl->base + AR71XX_GPIO_REG_IN,
|
||||
ctrl->base + AR71XX_GPIO_REG_SET,
|
||||
ctrl->base + AR71XX_GPIO_REG_CLEAR,
|
||||
@@ -271,45 +272,33 @@ static int ath79_gpio_probe(struct platform_device *pdev)
|
||||
oe_inverted ? ctrl->base + AR71XX_GPIO_REG_OE : NULL,
|
||||
0);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "bgpio_init failed\n");
|
||||
dev_err(dev, "bgpio_init failed\n");
|
||||
return err;
|
||||
}
|
||||
/* Use base 0 to stay compatible with legacy platforms */
|
||||
ctrl->gc.base = 0;
|
||||
|
||||
err = gpiochip_add_data(&ctrl->gc, ctrl);
|
||||
/* Optional interrupt setup */
|
||||
if (!np || of_property_read_bool(np, "interrupt-controller")) {
|
||||
girq = &ctrl->gc.irq;
|
||||
girq->chip = &ath79_gpio_irqchip;
|
||||
girq->parent_handler = ath79_gpio_irq_handler;
|
||||
girq->num_parents = 1;
|
||||
girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
|
||||
GFP_KERNEL);
|
||||
if (!girq->parents)
|
||||
return -ENOMEM;
|
||||
girq->parents[0] = platform_get_irq(pdev, 0);
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_simple_irq;
|
||||
}
|
||||
|
||||
err = devm_gpiochip_add_data(dev, &ctrl->gc, ctrl);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev,
|
||||
dev_err(dev,
|
||||
"cannot add AR71xx GPIO chip, error=%d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (np && !of_property_read_bool(np, "interrupt-controller"))
|
||||
return 0;
|
||||
|
||||
err = gpiochip_irqchip_add(&ctrl->gc, &ath79_gpio_irqchip, 0,
|
||||
handle_simple_irq, IRQ_TYPE_NONE);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n");
|
||||
goto gpiochip_remove;
|
||||
}
|
||||
|
||||
gpiochip_set_chained_irqchip(&ctrl->gc, &ath79_gpio_irqchip,
|
||||
platform_get_irq(pdev, 0),
|
||||
ath79_gpio_irq_handler);
|
||||
|
||||
return 0;
|
||||
|
||||
gpiochip_remove:
|
||||
gpiochip_remove(&ctrl->gc);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ath79_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ath79_gpio_ctrl *ctrl = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(&ctrl->gc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -319,7 +308,6 @@ static struct platform_driver ath79_gpio_driver = {
|
||||
.of_match_table = ath79_gpio_of_match,
|
||||
},
|
||||
.probe = ath79_gpio_probe,
|
||||
.remove = ath79_gpio_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(ath79_gpio_driver);
|
||||
|
@@ -297,7 +297,7 @@ static int davinci_gpio_probe(struct platform_device *pdev)
|
||||
static void gpio_irq_disable(struct irq_data *d)
|
||||
{
|
||||
struct davinci_gpio_regs __iomem *g = irq2regs(d);
|
||||
u32 mask = (u32) irq_data_get_irq_handler_data(d);
|
||||
uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d);
|
||||
|
||||
writel_relaxed(mask, &g->clr_falling);
|
||||
writel_relaxed(mask, &g->clr_rising);
|
||||
@@ -306,7 +306,7 @@ static void gpio_irq_disable(struct irq_data *d)
|
||||
static void gpio_irq_enable(struct irq_data *d)
|
||||
{
|
||||
struct davinci_gpio_regs __iomem *g = irq2regs(d);
|
||||
u32 mask = (u32) irq_data_get_irq_handler_data(d);
|
||||
uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d);
|
||||
unsigned status = irqd_get_trigger_type(d);
|
||||
|
||||
status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
|
||||
@@ -447,7 +447,7 @@ davinci_gpio_irq_map(struct irq_domain *d, unsigned int irq,
|
||||
"davinci_gpio");
|
||||
irq_set_irq_type(irq, IRQ_TYPE_NONE);
|
||||
irq_set_chip_data(irq, (__force void *)g);
|
||||
irq_set_handler_data(irq, (void *)__gpio_mask(hw));
|
||||
irq_set_handler_data(irq, (void *)(uintptr_t)__gpio_mask(hw));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -632,6 +632,7 @@ done:
|
||||
|
||||
static const struct of_device_id davinci_gpio_ids[] = {
|
||||
{ .compatible = "ti,keystone-gpio", keystone_gpio_get_irq_chip},
|
||||
{ .compatible = "ti,am654-gpio", keystone_gpio_get_irq_chip},
|
||||
{ .compatible = "ti,dm6441-gpio", davinci_gpio_get_irq_chip},
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
@@ -568,7 +568,6 @@ static int sprd_eic_probe(struct platform_device *pdev)
|
||||
const struct sprd_eic_variant_data *pdata;
|
||||
struct gpio_irq_chip *irq;
|
||||
struct sprd_eic *sprd_eic;
|
||||
struct resource *res;
|
||||
int ret, i;
|
||||
|
||||
pdata = of_device_get_match_data(&pdev->dev);
|
||||
@@ -597,13 +596,9 @@ static int sprd_eic_probe(struct platform_device *pdev)
|
||||
* have one bank EIC, thus base[1] and base[2] can be
|
||||
* optional.
|
||||
*/
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, i);
|
||||
if (!res)
|
||||
continue;
|
||||
|
||||
sprd_eic->base[i] = devm_ioremap_resource(&pdev->dev, res);
|
||||
sprd_eic->base[i] = devm_platform_ioremap_resource(pdev, i);
|
||||
if (IS_ERR(sprd_eic->base[i]))
|
||||
return PTR_ERR(sprd_eic->base[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
sprd_eic->chip.label = sprd_eic_label_name[sprd_eic->type];
|
||||
|
@@ -270,10 +270,8 @@ static int em_gio_probe(struct platform_device *pdev)
|
||||
int ret;
|
||||
|
||||
p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
|
||||
if (!p) {
|
||||
ret = -ENOMEM;
|
||||
goto err0;
|
||||
}
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
p->pdev = pdev;
|
||||
platform_set_drvdata(pdev, p);
|
||||
@@ -286,30 +284,22 @@ static int em_gio_probe(struct platform_device *pdev)
|
||||
|
||||
if (!io[0] || !io[1] || !irq[0] || !irq[1]) {
|
||||
dev_err(&pdev->dev, "missing IRQ or IOMEM\n");
|
||||
ret = -EINVAL;
|
||||
goto err0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
p->base0 = devm_ioremap_nocache(&pdev->dev, io[0]->start,
|
||||
resource_size(io[0]));
|
||||
if (!p->base0) {
|
||||
dev_err(&pdev->dev, "failed to remap low I/O memory\n");
|
||||
ret = -ENXIO;
|
||||
goto err0;
|
||||
}
|
||||
if (!p->base0)
|
||||
return -ENOMEM;
|
||||
|
||||
p->base1 = devm_ioremap_nocache(&pdev->dev, io[1]->start,
|
||||
resource_size(io[1]));
|
||||
if (!p->base1) {
|
||||
dev_err(&pdev->dev, "failed to remap high I/O memory\n");
|
||||
ret = -ENXIO;
|
||||
goto err0;
|
||||
}
|
||||
if (!p->base1)
|
||||
return -ENOMEM;
|
||||
|
||||
if (of_property_read_u32(pdev->dev.of_node, "ngpios", &ngpios)) {
|
||||
dev_err(&pdev->dev, "Missing ngpios OF property\n");
|
||||
ret = -EINVAL;
|
||||
goto err0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gpio_chip = &p->gpio_chip;
|
||||
@@ -339,9 +329,8 @@ static int em_gio_probe(struct platform_device *pdev)
|
||||
p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, ngpios, 0,
|
||||
&em_gio_irq_domain_ops, p);
|
||||
if (!p->irq_domain) {
|
||||
ret = -ENXIO;
|
||||
dev_err(&pdev->dev, "cannot initialize irq domain\n");
|
||||
goto err0;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
if (devm_request_irq(&pdev->dev, irq[0]->start,
|
||||
@@ -358,7 +347,7 @@ static int em_gio_probe(struct platform_device *pdev)
|
||||
goto err1;
|
||||
}
|
||||
|
||||
ret = gpiochip_add_data(gpio_chip, p);
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, gpio_chip, p);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to add GPIO controller\n");
|
||||
goto err1;
|
||||
@@ -368,7 +357,6 @@ static int em_gio_probe(struct platform_device *pdev)
|
||||
|
||||
err1:
|
||||
irq_domain_remove(p->irq_domain);
|
||||
err0:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -376,8 +364,6 @@ static int em_gio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct em_gio_priv *p = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(&p->gpio_chip);
|
||||
|
||||
irq_domain_remove(p->irq_domain);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -393,16 +393,13 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
|
||||
static int ep93xx_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ep93xx_gpio *epg;
|
||||
struct resource *res;
|
||||
int i;
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
epg = devm_kzalloc(dev, sizeof(*epg), GFP_KERNEL);
|
||||
epg = devm_kzalloc(&pdev->dev, sizeof(*epg), GFP_KERNEL);
|
||||
if (!epg)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
epg->base = devm_ioremap_resource(dev, res);
|
||||
epg->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(epg->base))
|
||||
return PTR_ERR(epg->base);
|
||||
|
||||
|
@@ -226,6 +226,7 @@ static int ftgpio_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ftgpio_gpio *g;
|
||||
struct gpio_irq_chip *girq;
|
||||
int irq;
|
||||
int ret;
|
||||
|
||||
@@ -277,6 +278,24 @@ static int ftgpio_gpio_probe(struct platform_device *pdev)
|
||||
if (!IS_ERR(g->clk))
|
||||
g->gc.set_config = ftgpio_gpio_set_config;
|
||||
|
||||
g->irq.name = "FTGPIO010";
|
||||
g->irq.irq_ack = ftgpio_gpio_ack_irq;
|
||||
g->irq.irq_mask = ftgpio_gpio_mask_irq;
|
||||
g->irq.irq_unmask = ftgpio_gpio_unmask_irq;
|
||||
g->irq.irq_set_type = ftgpio_gpio_set_irq_type;
|
||||
|
||||
girq = &g->gc.irq;
|
||||
girq->chip = &g->irq;
|
||||
girq->parent_handler = ftgpio_gpio_irq_handler;
|
||||
girq->num_parents = 1;
|
||||
girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
|
||||
GFP_KERNEL);
|
||||
if (!girq->parents)
|
||||
return -ENOMEM;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_bad_irq;
|
||||
girq->parents[0] = irq;
|
||||
|
||||
ret = devm_gpiochip_add_data(dev, &g->gc, g);
|
||||
if (ret)
|
||||
goto dis_clk;
|
||||
@@ -289,22 +308,6 @@ static int ftgpio_gpio_probe(struct platform_device *pdev)
|
||||
/* Clear any use of debounce */
|
||||
writel(0x0, g->base + GPIO_DEBOUNCE_EN);
|
||||
|
||||
g->irq.name = "FTGPIO010";
|
||||
g->irq.irq_ack = ftgpio_gpio_ack_irq;
|
||||
g->irq.irq_mask = ftgpio_gpio_mask_irq;
|
||||
g->irq.irq_unmask = ftgpio_gpio_unmask_irq;
|
||||
g->irq.irq_set_type = ftgpio_gpio_set_irq_type;
|
||||
|
||||
ret = gpiochip_irqchip_add(&g->gc, &g->irq,
|
||||
0, handle_bad_irq,
|
||||
IRQ_TYPE_NONE);
|
||||
if (ret) {
|
||||
dev_info(dev, "could not add irqchip\n");
|
||||
goto dis_clk;
|
||||
}
|
||||
gpiochip_set_chained_irqchip(&g->gc, &g->irq,
|
||||
irq, ftgpio_gpio_irq_handler);
|
||||
|
||||
platform_set_drvdata(pdev, g);
|
||||
dev_info(dev, "FTGPIO010 @%p registered\n", g->base);
|
||||
|
||||
|
@@ -329,7 +329,6 @@ static int grgpio_probe(struct platform_device *ofdev)
|
||||
void __iomem *regs;
|
||||
struct gpio_chip *gc;
|
||||
struct grgpio_priv *priv;
|
||||
struct resource *res;
|
||||
int err;
|
||||
u32 prop;
|
||||
s32 *irqmap;
|
||||
@@ -340,8 +339,7 @@ static int grgpio_probe(struct platform_device *ofdev)
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
|
||||
regs = devm_ioremap_resource(&ofdev->dev, res);
|
||||
regs = devm_platform_ioremap_resource(ofdev, 0);
|
||||
if (IS_ERR(regs))
|
||||
return PTR_ERR(regs);
|
||||
|
||||
|
@@ -205,20 +205,20 @@ static int ixp4xx_gpio_irq_domain_translate(struct irq_domain *domain,
|
||||
unsigned long *hwirq,
|
||||
unsigned int *type)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* We support standard DT translation */
|
||||
if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) {
|
||||
*hwirq = fwspec->param[0];
|
||||
*type = fwspec->param[1];
|
||||
return 0;
|
||||
return irq_domain_translate_twocell(domain, fwspec,
|
||||
hwirq, type);
|
||||
}
|
||||
|
||||
/* This goes away when we transition to DT */
|
||||
if (is_fwnode_irqchip(fwspec->fwnode)) {
|
||||
if (fwspec->param_count != 2)
|
||||
return -EINVAL;
|
||||
*hwirq = fwspec->param[0];
|
||||
*type = fwspec->param[1];
|
||||
ret = irq_domain_translate_twocell(domain, fwspec,
|
||||
hwirq, type);
|
||||
if (ret)
|
||||
return ret;
|
||||
WARN_ON(*type == IRQ_TYPE_NONE);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -140,18 +140,17 @@ static void ttl_setup_device(struct ttl_module *mod)
|
||||
static int ttl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct janz_platform_data *pdata;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ttl_module *mod;
|
||||
struct gpio_chip *gpio;
|
||||
int ret;
|
||||
|
||||
pdata = dev_get_platdata(&pdev->dev);
|
||||
if (!pdata) {
|
||||
dev_err(dev, "no platform data\n");
|
||||
dev_err(&pdev->dev, "no platform data\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
mod = devm_kzalloc(dev, sizeof(*mod), GFP_KERNEL);
|
||||
mod = devm_kzalloc(&pdev->dev, sizeof(*mod), GFP_KERNEL);
|
||||
if (!mod)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -177,9 +176,9 @@ static int ttl_probe(struct platform_device *pdev)
|
||||
gpio->base = -1;
|
||||
gpio->ngpio = 20;
|
||||
|
||||
ret = devm_gpiochip_add_data(dev, gpio, NULL);
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, gpio, NULL);
|
||||
if (ret) {
|
||||
dev_err(dev, "unable to add GPIO chip\n");
|
||||
dev_err(&pdev->dev, "unable to add GPIO chip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -1,12 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* GPIO support for Cirrus Logic Madera codecs
|
||||
*
|
||||
* Copyright (C) 2015-2018 Cirrus Logic
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; version 2.
|
||||
*/
|
||||
|
||||
#include <linux/gpio/driver.h>
|
||||
|
@@ -649,12 +649,12 @@ static int max732x_probe(struct i2c_client *client,
|
||||
case 0x60:
|
||||
chip->client_group_a = client;
|
||||
if (nr_port > 8) {
|
||||
c = i2c_new_dummy(client->adapter, addr_b);
|
||||
if (!c) {
|
||||
c = devm_i2c_new_dummy_device(&client->dev,
|
||||
client->adapter, addr_b);
|
||||
if (IS_ERR(c)) {
|
||||
dev_err(&client->dev,
|
||||
"Failed to allocate I2C device\n");
|
||||
ret = -ENODEV;
|
||||
goto out_failed;
|
||||
return PTR_ERR(c);
|
||||
}
|
||||
chip->client_group_b = chip->client_dummy = c;
|
||||
}
|
||||
@@ -662,12 +662,12 @@ static int max732x_probe(struct i2c_client *client,
|
||||
case 0x50:
|
||||
chip->client_group_b = client;
|
||||
if (nr_port > 8) {
|
||||
c = i2c_new_dummy(client->adapter, addr_a);
|
||||
if (!c) {
|
||||
c = devm_i2c_new_dummy_device(&client->dev,
|
||||
client->adapter, addr_a);
|
||||
if (IS_ERR(c)) {
|
||||
dev_err(&client->dev,
|
||||
"Failed to allocate I2C device\n");
|
||||
ret = -ENODEV;
|
||||
goto out_failed;
|
||||
return PTR_ERR(c);
|
||||
}
|
||||
chip->client_group_a = chip->client_dummy = c;
|
||||
}
|
||||
@@ -675,37 +675,33 @@ static int max732x_probe(struct i2c_client *client,
|
||||
default:
|
||||
dev_err(&client->dev, "invalid I2C address specified %02x\n",
|
||||
client->addr);
|
||||
ret = -EINVAL;
|
||||
goto out_failed;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (nr_port > 8 && !chip->client_dummy) {
|
||||
dev_err(&client->dev,
|
||||
"Failed to allocate second group I2C device\n");
|
||||
ret = -ENODEV;
|
||||
goto out_failed;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mutex_init(&chip->lock);
|
||||
|
||||
ret = max732x_readb(chip, is_group_a(chip, 0), &chip->reg_out[0]);
|
||||
if (ret)
|
||||
goto out_failed;
|
||||
return ret;
|
||||
if (nr_port > 8) {
|
||||
ret = max732x_readb(chip, is_group_a(chip, 8), &chip->reg_out[1]);
|
||||
if (ret)
|
||||
goto out_failed;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = gpiochip_add_data(&chip->gpio_chip, chip);
|
||||
ret = devm_gpiochip_add_data(&client->dev, &chip->gpio_chip, chip);
|
||||
if (ret)
|
||||
goto out_failed;
|
||||
return ret;
|
||||
|
||||
ret = max732x_irq_setup(chip, id);
|
||||
if (ret) {
|
||||
gpiochip_remove(&chip->gpio_chip);
|
||||
goto out_failed;
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (pdata && pdata->setup) {
|
||||
ret = pdata->setup(client, chip->gpio_chip.base,
|
||||
@@ -716,10 +712,6 @@ static int max732x_probe(struct i2c_client *client,
|
||||
|
||||
i2c_set_clientdata(client, chip);
|
||||
return 0;
|
||||
|
||||
out_failed:
|
||||
i2c_unregister_device(chip->client_dummy);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max732x_remove(struct i2c_client *client)
|
||||
@@ -739,11 +731,6 @@ static int max732x_remove(struct i2c_client *client)
|
||||
}
|
||||
}
|
||||
|
||||
gpiochip_remove(&chip->gpio_chip);
|
||||
|
||||
/* unregister any dummy i2c_client */
|
||||
i2c_unregister_device(chip->client_dummy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -315,7 +315,6 @@ static void gpio_mockup_debugfs_setup(struct device *dev,
|
||||
struct gpio_mockup_chip *chip)
|
||||
{
|
||||
struct gpio_mockup_dbgfs_private *priv;
|
||||
struct dentry *evfile;
|
||||
struct gpio_chip *gc;
|
||||
const char *devname;
|
||||
char *name;
|
||||
@@ -325,32 +324,25 @@ static void gpio_mockup_debugfs_setup(struct device *dev,
|
||||
devname = dev_name(&gc->gpiodev->dev);
|
||||
|
||||
chip->dbg_dir = debugfs_create_dir(devname, gpio_mockup_dbg_dir);
|
||||
if (IS_ERR_OR_NULL(chip->dbg_dir))
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < gc->ngpio; i++) {
|
||||
name = devm_kasprintf(dev, GFP_KERNEL, "%d", i);
|
||||
if (!name)
|
||||
goto err;
|
||||
return;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
goto err;
|
||||
return;
|
||||
|
||||
priv->chip = chip;
|
||||
priv->offset = i;
|
||||
priv->desc = &gc->gpiodev->descs[i];
|
||||
|
||||
evfile = debugfs_create_file(name, 0200, chip->dbg_dir, priv,
|
||||
&gpio_mockup_debugfs_ops);
|
||||
if (IS_ERR_OR_NULL(evfile))
|
||||
goto err;
|
||||
debugfs_create_file(name, 0200, chip->dbg_dir, priv,
|
||||
&gpio_mockup_debugfs_ops);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
err:
|
||||
dev_err(dev, "error creating debugfs files\n");
|
||||
}
|
||||
|
||||
static int gpio_mockup_name_lines(struct device *dev,
|
||||
@@ -447,8 +439,7 @@ static int gpio_mockup_probe(struct platform_device *pdev)
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
if (!IS_ERR_OR_NULL(gpio_mockup_dbg_dir))
|
||||
gpio_mockup_debugfs_setup(dev, chip);
|
||||
gpio_mockup_debugfs_setup(dev, chip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -501,8 +492,6 @@ static int __init gpio_mockup_init(void)
|
||||
}
|
||||
|
||||
gpio_mockup_dbg_dir = debugfs_create_dir("gpio-mockup", NULL);
|
||||
if (IS_ERR_OR_NULL(gpio_mockup_dbg_dir))
|
||||
gpio_mockup_err("error creating debugfs directory\n");
|
||||
|
||||
err = platform_driver_register(&gpio_mockup_driver);
|
||||
if (err) {
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
@@ -618,18 +619,14 @@ static int mvebu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
ret = -EBUSY;
|
||||
} else {
|
||||
desc = gpiochip_request_own_desc(&mvchip->chip,
|
||||
pwm->hwpwm, "mvebu-pwm", 0);
|
||||
pwm->hwpwm, "mvebu-pwm",
|
||||
GPIO_ACTIVE_HIGH,
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(desc)) {
|
||||
ret = PTR_ERR(desc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = gpiod_direction_output(desc, 0);
|
||||
if (ret) {
|
||||
gpiochip_free_own_desc(desc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
mvpwm->gpiod = desc;
|
||||
}
|
||||
out:
|
||||
|
@@ -44,8 +44,9 @@ struct gpio_regs {
|
||||
};
|
||||
|
||||
struct gpio_bank {
|
||||
struct list_head node;
|
||||
void __iomem *base;
|
||||
const struct omap_gpio_reg_offs *regs;
|
||||
|
||||
int irq;
|
||||
u32 non_wakeup_gpios;
|
||||
u32 enabled_non_wakeup_gpios;
|
||||
@@ -72,11 +73,7 @@ struct gpio_bank {
|
||||
int context_loss_count;
|
||||
|
||||
void (*set_dataout)(struct gpio_bank *bank, unsigned gpio, int enable);
|
||||
void (*set_dataout_multiple)(struct gpio_bank *bank,
|
||||
unsigned long *mask, unsigned long *bits);
|
||||
int (*get_context_loss_count)(struct device *dev);
|
||||
|
||||
struct omap_gpio_reg_offs *regs;
|
||||
};
|
||||
|
||||
#define GPIO_MOD_CTRL_BIT BIT(0)
|
||||
@@ -92,20 +89,25 @@ static inline struct gpio_bank *omap_irq_data_get_bank(struct irq_data *d)
|
||||
return gpiochip_get_data(chip);
|
||||
}
|
||||
|
||||
static inline u32 omap_gpio_rmw(void __iomem *reg, u32 mask, bool set)
|
||||
{
|
||||
u32 val = readl_relaxed(reg);
|
||||
|
||||
if (set)
|
||||
val |= mask;
|
||||
else
|
||||
val &= ~mask;
|
||||
|
||||
writel_relaxed(val, reg);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void omap_set_gpio_direction(struct gpio_bank *bank, int gpio,
|
||||
int is_input)
|
||||
{
|
||||
void __iomem *reg = bank->base;
|
||||
u32 l;
|
||||
|
||||
reg += bank->regs->direction;
|
||||
l = readl_relaxed(reg);
|
||||
if (is_input)
|
||||
l |= BIT(gpio);
|
||||
else
|
||||
l &= ~(BIT(gpio));
|
||||
writel_relaxed(l, reg);
|
||||
bank->context.oe = l;
|
||||
bank->context.oe = omap_gpio_rmw(bank->base + bank->regs->direction,
|
||||
BIT(gpio), is_input);
|
||||
}
|
||||
|
||||
|
||||
@@ -131,88 +133,8 @@ static void omap_set_gpio_dataout_reg(struct gpio_bank *bank, unsigned offset,
|
||||
static void omap_set_gpio_dataout_mask(struct gpio_bank *bank, unsigned offset,
|
||||
int enable)
|
||||
{
|
||||
void __iomem *reg = bank->base + bank->regs->dataout;
|
||||
u32 gpio_bit = BIT(offset);
|
||||
u32 l;
|
||||
|
||||
l = readl_relaxed(reg);
|
||||
if (enable)
|
||||
l |= gpio_bit;
|
||||
else
|
||||
l &= ~gpio_bit;
|
||||
writel_relaxed(l, reg);
|
||||
bank->context.dataout = l;
|
||||
}
|
||||
|
||||
static int omap_get_gpio_datain(struct gpio_bank *bank, int offset)
|
||||
{
|
||||
void __iomem *reg = bank->base + bank->regs->datain;
|
||||
|
||||
return (readl_relaxed(reg) & (BIT(offset))) != 0;
|
||||
}
|
||||
|
||||
static int omap_get_gpio_dataout(struct gpio_bank *bank, int offset)
|
||||
{
|
||||
void __iomem *reg = bank->base + bank->regs->dataout;
|
||||
|
||||
return (readl_relaxed(reg) & (BIT(offset))) != 0;
|
||||
}
|
||||
|
||||
/* set multiple data out values using dedicate set/clear register */
|
||||
static void omap_set_gpio_dataout_reg_multiple(struct gpio_bank *bank,
|
||||
unsigned long *mask,
|
||||
unsigned long *bits)
|
||||
{
|
||||
void __iomem *reg = bank->base;
|
||||
u32 l;
|
||||
|
||||
l = *bits & *mask;
|
||||
writel_relaxed(l, reg + bank->regs->set_dataout);
|
||||
bank->context.dataout |= l;
|
||||
|
||||
l = ~*bits & *mask;
|
||||
writel_relaxed(l, reg + bank->regs->clr_dataout);
|
||||
bank->context.dataout &= ~l;
|
||||
}
|
||||
|
||||
/* set multiple data out values using mask register */
|
||||
static void omap_set_gpio_dataout_mask_multiple(struct gpio_bank *bank,
|
||||
unsigned long *mask,
|
||||
unsigned long *bits)
|
||||
{
|
||||
void __iomem *reg = bank->base + bank->regs->dataout;
|
||||
u32 l = (readl_relaxed(reg) & ~*mask) | (*bits & *mask);
|
||||
|
||||
writel_relaxed(l, reg);
|
||||
bank->context.dataout = l;
|
||||
}
|
||||
|
||||
static unsigned long omap_get_gpio_datain_multiple(struct gpio_bank *bank,
|
||||
unsigned long *mask)
|
||||
{
|
||||
void __iomem *reg = bank->base + bank->regs->datain;
|
||||
|
||||
return readl_relaxed(reg) & *mask;
|
||||
}
|
||||
|
||||
static unsigned long omap_get_gpio_dataout_multiple(struct gpio_bank *bank,
|
||||
unsigned long *mask)
|
||||
{
|
||||
void __iomem *reg = bank->base + bank->regs->dataout;
|
||||
|
||||
return readl_relaxed(reg) & *mask;
|
||||
}
|
||||
|
||||
static inline void omap_gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
|
||||
{
|
||||
int l = readl_relaxed(base + reg);
|
||||
|
||||
if (set)
|
||||
l |= mask;
|
||||
else
|
||||
l &= ~mask;
|
||||
|
||||
writel_relaxed(l, base + reg);
|
||||
bank->context.dataout = omap_gpio_rmw(bank->base + bank->regs->dataout,
|
||||
BIT(offset), enable);
|
||||
}
|
||||
|
||||
static inline void omap_gpio_dbck_enable(struct gpio_bank *bank)
|
||||
@@ -256,7 +178,6 @@ static inline void omap_gpio_dbck_disable(struct gpio_bank *bank)
|
||||
static int omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
|
||||
unsigned debounce)
|
||||
{
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
u32 l;
|
||||
bool enable = !!debounce;
|
||||
@@ -273,19 +194,11 @@ static int omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
|
||||
l = BIT(offset);
|
||||
|
||||
clk_enable(bank->dbck);
|
||||
reg = bank->base + bank->regs->debounce;
|
||||
writel_relaxed(debounce, reg);
|
||||
writel_relaxed(debounce, bank->base + bank->regs->debounce);
|
||||
|
||||
reg = bank->base + bank->regs->debounce_en;
|
||||
val = readl_relaxed(reg);
|
||||
|
||||
if (enable)
|
||||
val |= l;
|
||||
else
|
||||
val &= ~l;
|
||||
val = omap_gpio_rmw(bank->base + bank->regs->debounce_en, l, enable);
|
||||
bank->dbck_enable_mask = val;
|
||||
|
||||
writel_relaxed(val, reg);
|
||||
clk_disable(bank->dbck);
|
||||
/*
|
||||
* Enable debounce clock per module.
|
||||
@@ -360,9 +273,9 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio,
|
||||
void __iomem *base = bank->base;
|
||||
u32 gpio_bit = BIT(gpio);
|
||||
|
||||
omap_gpio_rmw(base, bank->regs->leveldetect0, gpio_bit,
|
||||
omap_gpio_rmw(base + bank->regs->leveldetect0, gpio_bit,
|
||||
trigger & IRQ_TYPE_LEVEL_LOW);
|
||||
omap_gpio_rmw(base, bank->regs->leveldetect1, gpio_bit,
|
||||
omap_gpio_rmw(base + bank->regs->leveldetect1, gpio_bit,
|
||||
trigger & IRQ_TYPE_LEVEL_HIGH);
|
||||
|
||||
/*
|
||||
@@ -370,9 +283,9 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio,
|
||||
* to be woken from idle state. Set the appropriate edge detection
|
||||
* in addition to the level detection.
|
||||
*/
|
||||
omap_gpio_rmw(base, bank->regs->risingdetect, gpio_bit,
|
||||
omap_gpio_rmw(base + bank->regs->risingdetect, gpio_bit,
|
||||
trigger & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH));
|
||||
omap_gpio_rmw(base, bank->regs->fallingdetect, gpio_bit,
|
||||
omap_gpio_rmw(base + bank->regs->fallingdetect, gpio_bit,
|
||||
trigger & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW));
|
||||
|
||||
bank->context.leveldetect0 =
|
||||
@@ -384,11 +297,8 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio,
|
||||
bank->context.fallingdetect =
|
||||
readl_relaxed(bank->base + bank->regs->fallingdetect);
|
||||
|
||||
if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
|
||||
omap_gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0);
|
||||
bank->context.wake_en =
|
||||
readl_relaxed(bank->base + bank->regs->wkup_en);
|
||||
}
|
||||
bank->level_mask = bank->context.leveldetect0 |
|
||||
bank->context.leveldetect1;
|
||||
|
||||
/* This part needs to be executed always for OMAP{34xx, 44xx} */
|
||||
if (!bank->regs->irqctrl && !omap_gpio_is_off_wakeup_capable(bank, gpio)) {
|
||||
@@ -403,44 +313,25 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio,
|
||||
else
|
||||
bank->enabled_non_wakeup_gpios &= ~gpio_bit;
|
||||
}
|
||||
|
||||
bank->level_mask =
|
||||
readl_relaxed(bank->base + bank->regs->leveldetect0) |
|
||||
readl_relaxed(bank->base + bank->regs->leveldetect1);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1
|
||||
/*
|
||||
* This only applies to chips that can't do both rising and falling edge
|
||||
* detection at once. For all other chips, this function is a noop.
|
||||
*/
|
||||
static void omap_toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
|
||||
{
|
||||
void __iomem *reg = bank->base;
|
||||
u32 l = 0;
|
||||
if (IS_ENABLED(CONFIG_ARCH_OMAP1) && bank->regs->irqctrl) {
|
||||
void __iomem *reg = bank->base + bank->regs->irqctrl;
|
||||
|
||||
if (!bank->regs->irqctrl)
|
||||
return;
|
||||
|
||||
reg += bank->regs->irqctrl;
|
||||
|
||||
l = readl_relaxed(reg);
|
||||
if ((l >> gpio) & 1)
|
||||
l &= ~(BIT(gpio));
|
||||
else
|
||||
l |= BIT(gpio);
|
||||
|
||||
writel_relaxed(l, reg);
|
||||
writel_relaxed(readl_relaxed(reg) ^ BIT(gpio), reg);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void omap_toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) {}
|
||||
#endif
|
||||
|
||||
static int omap_set_gpio_triggering(struct gpio_bank *bank, int gpio,
|
||||
unsigned trigger)
|
||||
{
|
||||
void __iomem *reg = bank->base;
|
||||
void __iomem *base = bank->base;
|
||||
u32 l = 0;
|
||||
|
||||
if (bank->regs->leveldetect0 && bank->regs->wkup_en) {
|
||||
@@ -472,11 +363,6 @@ static int omap_set_gpio_triggering(struct gpio_bank *bank, int gpio,
|
||||
l |= 2 << (gpio << 1);
|
||||
if (trigger & IRQ_TYPE_EDGE_FALLING)
|
||||
l |= BIT(gpio << 1);
|
||||
|
||||
/* Enable wake-up during idle for dynamic tick */
|
||||
omap_gpio_rmw(base, bank->regs->wkup_en, BIT(gpio), trigger);
|
||||
bank->context.wake_en =
|
||||
readl_relaxed(bank->base + bank->regs->wkup_en);
|
||||
writel_relaxed(l, reg);
|
||||
}
|
||||
return 0;
|
||||
@@ -505,17 +391,6 @@ static void omap_enable_gpio_module(struct gpio_bank *bank, unsigned offset)
|
||||
|
||||
static void omap_disable_gpio_module(struct gpio_bank *bank, unsigned offset)
|
||||
{
|
||||
void __iomem *base = bank->base;
|
||||
|
||||
if (bank->regs->wkup_en &&
|
||||
!LINE_USED(bank->mod_usage, offset) &&
|
||||
!LINE_USED(bank->irq_usage, offset)) {
|
||||
/* Disable wake-up during idle for dynamic tick */
|
||||
omap_gpio_rmw(base, bank->regs->wkup_en, BIT(offset), 0);
|
||||
bank->context.wake_en =
|
||||
readl_relaxed(bank->base + bank->regs->wkup_en);
|
||||
}
|
||||
|
||||
if (bank->regs->ctrl && !BANK_USED(bank)) {
|
||||
void __iomem *reg = bank->base + bank->regs->ctrl;
|
||||
u32 ctrl;
|
||||
@@ -626,57 +501,39 @@ static u32 omap_get_gpio_irqbank_mask(struct gpio_bank *bank)
|
||||
return l;
|
||||
}
|
||||
|
||||
static void omap_enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
|
||||
{
|
||||
void __iomem *reg = bank->base;
|
||||
u32 l;
|
||||
|
||||
if (bank->regs->set_irqenable) {
|
||||
reg += bank->regs->set_irqenable;
|
||||
l = gpio_mask;
|
||||
bank->context.irqenable1 |= gpio_mask;
|
||||
} else {
|
||||
reg += bank->regs->irqenable;
|
||||
l = readl_relaxed(reg);
|
||||
if (bank->regs->irqenable_inv)
|
||||
l &= ~gpio_mask;
|
||||
else
|
||||
l |= gpio_mask;
|
||||
bank->context.irqenable1 = l;
|
||||
}
|
||||
|
||||
writel_relaxed(l, reg);
|
||||
}
|
||||
|
||||
static void omap_disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
|
||||
{
|
||||
void __iomem *reg = bank->base;
|
||||
u32 l;
|
||||
|
||||
if (bank->regs->clr_irqenable) {
|
||||
reg += bank->regs->clr_irqenable;
|
||||
l = gpio_mask;
|
||||
bank->context.irqenable1 &= ~gpio_mask;
|
||||
} else {
|
||||
reg += bank->regs->irqenable;
|
||||
l = readl_relaxed(reg);
|
||||
if (bank->regs->irqenable_inv)
|
||||
l |= gpio_mask;
|
||||
else
|
||||
l &= ~gpio_mask;
|
||||
bank->context.irqenable1 = l;
|
||||
}
|
||||
|
||||
writel_relaxed(l, reg);
|
||||
}
|
||||
|
||||
static inline void omap_set_gpio_irqenable(struct gpio_bank *bank,
|
||||
unsigned offset, int enable)
|
||||
{
|
||||
if (enable)
|
||||
omap_enable_gpio_irqbank(bank, BIT(offset));
|
||||
else
|
||||
omap_disable_gpio_irqbank(bank, BIT(offset));
|
||||
void __iomem *reg = bank->base;
|
||||
u32 gpio_mask = BIT(offset);
|
||||
|
||||
if (bank->regs->set_irqenable && bank->regs->clr_irqenable) {
|
||||
if (enable) {
|
||||
reg += bank->regs->set_irqenable;
|
||||
bank->context.irqenable1 |= gpio_mask;
|
||||
} else {
|
||||
reg += bank->regs->clr_irqenable;
|
||||
bank->context.irqenable1 &= ~gpio_mask;
|
||||
}
|
||||
writel_relaxed(gpio_mask, reg);
|
||||
} else {
|
||||
bank->context.irqenable1 =
|
||||
omap_gpio_rmw(reg + bank->regs->irqenable, gpio_mask,
|
||||
enable ^ bank->regs->irqenable_inv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Program GPIO wakeup along with IRQ enable to satisfy OMAP4430 TRM
|
||||
* note requiring correlation between the IRQ enable registers and
|
||||
* the wakeup registers. In any case, we want wakeup from idle
|
||||
* enabled for the GPIOs which support this feature.
|
||||
*/
|
||||
if (bank->regs->wkup_en &&
|
||||
(bank->regs->edgectrl1 || !(bank->non_wakeup_gpios & gpio_mask))) {
|
||||
bank->context.wake_en =
|
||||
omap_gpio_rmw(bank->base + bank->regs->wkup_en,
|
||||
gpio_mask, enable);
|
||||
}
|
||||
}
|
||||
|
||||
/* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
|
||||
@@ -687,38 +544,6 @@ static int omap_gpio_wake_enable(struct irq_data *d, unsigned int enable)
|
||||
return irq_set_irq_wake(bank->irq, enable);
|
||||
}
|
||||
|
||||
static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct gpio_bank *bank = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
pm_runtime_get_sync(chip->parent);
|
||||
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
omap_enable_gpio_module(bank, offset);
|
||||
bank->mod_usage |= BIT(offset);
|
||||
raw_spin_unlock_irqrestore(&bank->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct gpio_bank *bank = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
bank->mod_usage &= ~(BIT(offset));
|
||||
if (!LINE_USED(bank->irq_usage, offset)) {
|
||||
omap_set_gpio_direction(bank, offset, 1);
|
||||
omap_clear_gpio_debounce(bank, offset);
|
||||
}
|
||||
omap_disable_gpio_module(bank, offset);
|
||||
raw_spin_unlock_irqrestore(&bank->lock, flags);
|
||||
|
||||
pm_runtime_put(chip->parent);
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to unmask the GPIO bank interrupt as soon as possible to
|
||||
* avoid missing GPIO interrupts for other lines in the bank.
|
||||
@@ -731,7 +556,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
|
||||
static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)
|
||||
{
|
||||
void __iomem *isr_reg = NULL;
|
||||
u32 enabled, isr, level_mask;
|
||||
u32 enabled, isr, edge;
|
||||
unsigned int bit;
|
||||
struct gpio_bank *bank = gpiobank;
|
||||
unsigned long wa_lock_flags;
|
||||
@@ -751,16 +576,14 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)
|
||||
enabled = omap_get_gpio_irqbank_mask(bank);
|
||||
isr = readl_relaxed(isr_reg) & enabled;
|
||||
|
||||
if (bank->level_mask)
|
||||
level_mask = bank->level_mask & enabled;
|
||||
else
|
||||
level_mask = 0;
|
||||
|
||||
/* clear edge sensitive interrupts before handler(s) are
|
||||
called so that we don't miss any interrupt occurred while
|
||||
executing them */
|
||||
if (isr & ~level_mask)
|
||||
omap_clear_gpio_irqbank(bank, isr & ~level_mask);
|
||||
/*
|
||||
* Clear edge sensitive interrupts before calling handler(s)
|
||||
* so subsequent edge transitions are not missed while the
|
||||
* handlers are running.
|
||||
*/
|
||||
edge = isr & ~bank->level_mask;
|
||||
if (edge)
|
||||
omap_clear_gpio_irqbank(bank, edge);
|
||||
|
||||
raw_spin_unlock_irqrestore(&bank->lock, lock_flags);
|
||||
|
||||
@@ -807,8 +630,6 @@ static unsigned int omap_gpio_irq_startup(struct irq_data *d)
|
||||
|
||||
if (!LINE_USED(bank->mod_usage, offset))
|
||||
omap_set_gpio_direction(bank, offset, 1);
|
||||
else if (!omap_gpio_is_input(bank, offset))
|
||||
goto err;
|
||||
omap_enable_gpio_module(bank, offset);
|
||||
bank->irq_usage |= BIT(offset);
|
||||
|
||||
@@ -816,9 +637,6 @@ static unsigned int omap_gpio_irq_startup(struct irq_data *d)
|
||||
omap_gpio_unmask_irq(d);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
raw_spin_unlock_irqrestore(&bank->lock, flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void omap_gpio_irq_shutdown(struct irq_data *d)
|
||||
@@ -829,9 +647,9 @@ static void omap_gpio_irq_shutdown(struct irq_data *d)
|
||||
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
bank->irq_usage &= ~(BIT(offset));
|
||||
omap_set_gpio_irqenable(bank, offset, 0);
|
||||
omap_clear_gpio_irqstatus(bank, offset);
|
||||
omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
|
||||
omap_clear_gpio_irqstatus(bank, offset);
|
||||
omap_set_gpio_irqenable(bank, offset, 0);
|
||||
if (!LINE_USED(bank->mod_usage, offset))
|
||||
omap_clear_gpio_debounce(bank, offset);
|
||||
omap_disable_gpio_module(bank, offset);
|
||||
@@ -852,14 +670,6 @@ static void gpio_irq_bus_sync_unlock(struct irq_data *data)
|
||||
pm_runtime_put(bank->chip.parent);
|
||||
}
|
||||
|
||||
static void omap_gpio_ack_irq(struct irq_data *d)
|
||||
{
|
||||
struct gpio_bank *bank = omap_irq_data_get_bank(d);
|
||||
unsigned offset = d->hwirq;
|
||||
|
||||
omap_clear_gpio_irqstatus(bank, offset);
|
||||
}
|
||||
|
||||
static void omap_gpio_mask_irq(struct irq_data *d)
|
||||
{
|
||||
struct gpio_bank *bank = omap_irq_data_get_bank(d);
|
||||
@@ -867,8 +677,8 @@ static void omap_gpio_mask_irq(struct irq_data *d)
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
omap_set_gpio_irqenable(bank, offset, 0);
|
||||
omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
|
||||
omap_set_gpio_irqenable(bank, offset, 0);
|
||||
raw_spin_unlock_irqrestore(&bank->lock, flags);
|
||||
}
|
||||
|
||||
@@ -880,9 +690,6 @@ static void omap_gpio_unmask_irq(struct irq_data *d)
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
if (trigger)
|
||||
omap_set_gpio_triggering(bank, offset, trigger);
|
||||
|
||||
omap_set_gpio_irqenable(bank, offset, 1);
|
||||
|
||||
/*
|
||||
@@ -890,9 +697,13 @@ static void omap_gpio_unmask_irq(struct irq_data *d)
|
||||
* is cleared, thus after the handler has run. OMAP4 needs this done
|
||||
* after enabing the interrupt to clear the wakeup status.
|
||||
*/
|
||||
if (bank->level_mask & BIT(offset))
|
||||
if (bank->regs->leveldetect0 && bank->regs->wkup_en &&
|
||||
trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
|
||||
omap_clear_gpio_irqstatus(bank, offset);
|
||||
|
||||
if (trigger)
|
||||
omap_set_gpio_triggering(bank, offset, trigger);
|
||||
|
||||
raw_spin_unlock_irqrestore(&bank->lock, flags);
|
||||
}
|
||||
|
||||
@@ -958,19 +769,44 @@ static inline void omap_mpuio_init(struct gpio_bank *bank)
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct gpio_bank *bank = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
pm_runtime_get_sync(chip->parent);
|
||||
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
omap_enable_gpio_module(bank, offset);
|
||||
bank->mod_usage |= BIT(offset);
|
||||
raw_spin_unlock_irqrestore(&bank->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct gpio_bank *bank = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
bank->mod_usage &= ~(BIT(offset));
|
||||
if (!LINE_USED(bank->irq_usage, offset)) {
|
||||
omap_set_gpio_direction(bank, offset, 1);
|
||||
omap_clear_gpio_debounce(bank, offset);
|
||||
}
|
||||
omap_disable_gpio_module(bank, offset);
|
||||
raw_spin_unlock_irqrestore(&bank->lock, flags);
|
||||
|
||||
pm_runtime_put(chip->parent);
|
||||
}
|
||||
|
||||
static int omap_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct gpio_bank *bank;
|
||||
unsigned long flags;
|
||||
void __iomem *reg;
|
||||
int dir;
|
||||
struct gpio_bank *bank = gpiochip_get_data(chip);
|
||||
|
||||
bank = gpiochip_get_data(chip);
|
||||
reg = bank->base + bank->regs->direction;
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
dir = !!(readl_relaxed(reg) & BIT(offset));
|
||||
raw_spin_unlock_irqrestore(&bank->lock, flags);
|
||||
return dir;
|
||||
return !!(readl_relaxed(bank->base + bank->regs->direction) &
|
||||
BIT(offset));
|
||||
}
|
||||
|
||||
static int omap_gpio_input(struct gpio_chip *chip, unsigned offset)
|
||||
@@ -987,14 +823,15 @@ static int omap_gpio_input(struct gpio_chip *chip, unsigned offset)
|
||||
|
||||
static int omap_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct gpio_bank *bank;
|
||||
|
||||
bank = gpiochip_get_data(chip);
|
||||
struct gpio_bank *bank = gpiochip_get_data(chip);
|
||||
void __iomem *reg;
|
||||
|
||||
if (omap_gpio_is_input(bank, offset))
|
||||
return omap_get_gpio_datain(bank, offset);
|
||||
reg = bank->base + bank->regs->datain;
|
||||
else
|
||||
return omap_get_gpio_dataout(bank, offset);
|
||||
reg = bank->base + bank->regs->dataout;
|
||||
|
||||
return (readl_relaxed(reg) & BIT(offset)) != 0;
|
||||
}
|
||||
|
||||
static int omap_gpio_output(struct gpio_chip *chip, unsigned offset, int value)
|
||||
@@ -1014,18 +851,20 @@ static int omap_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
|
||||
unsigned long *bits)
|
||||
{
|
||||
struct gpio_bank *bank = gpiochip_get_data(chip);
|
||||
void __iomem *reg = bank->base + bank->regs->direction;
|
||||
unsigned long in = readl_relaxed(reg), l;
|
||||
void __iomem *base = bank->base;
|
||||
u32 direction, m, val = 0;
|
||||
|
||||
*bits = 0;
|
||||
direction = readl_relaxed(base + bank->regs->direction);
|
||||
|
||||
l = in & *mask;
|
||||
if (l)
|
||||
*bits |= omap_get_gpio_datain_multiple(bank, &l);
|
||||
m = direction & *mask;
|
||||
if (m)
|
||||
val |= readl_relaxed(base + bank->regs->datain) & m;
|
||||
|
||||
l = ~in & *mask;
|
||||
if (l)
|
||||
*bits |= omap_get_gpio_dataout_multiple(bank, &l);
|
||||
m = ~direction & *mask;
|
||||
if (m)
|
||||
val |= readl_relaxed(base + bank->regs->dataout) & m;
|
||||
|
||||
*bits = val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1078,10 +917,14 @@ static void omap_gpio_set_multiple(struct gpio_chip *chip, unsigned long *mask,
|
||||
unsigned long *bits)
|
||||
{
|
||||
struct gpio_bank *bank = gpiochip_get_data(chip);
|
||||
void __iomem *reg = bank->base + bank->regs->dataout;
|
||||
unsigned long flags;
|
||||
u32 l;
|
||||
|
||||
raw_spin_lock_irqsave(&bank->lock, flags);
|
||||
bank->set_dataout_multiple(bank, mask, bits);
|
||||
l = (readl_relaxed(reg) & ~*mask) | (*bits & *mask);
|
||||
writel_relaxed(l, reg);
|
||||
bank->context.dataout = l;
|
||||
raw_spin_unlock_irqrestore(&bank->lock, flags);
|
||||
}
|
||||
|
||||
@@ -1115,9 +958,9 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
|
||||
return;
|
||||
}
|
||||
|
||||
omap_gpio_rmw(base, bank->regs->irqenable, l,
|
||||
omap_gpio_rmw(base + bank->regs->irqenable, l,
|
||||
bank->regs->irqenable_inv);
|
||||
omap_gpio_rmw(base, bank->regs->irqstatus, l,
|
||||
omap_gpio_rmw(base + bank->regs->irqstatus, l,
|
||||
!bank->regs->irqenable_inv);
|
||||
if (bank->regs->debounce_en)
|
||||
writel_relaxed(0, base + bank->regs->debounce_en);
|
||||
@@ -1180,11 +1023,8 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
||||
#endif
|
||||
|
||||
/* MPUIO is a bit different, reading IRQ status clears it */
|
||||
if (bank->is_mpuio) {
|
||||
irqc->irq_ack = dummy_irq_chip.irq_ack;
|
||||
if (!bank->regs->wkup_en)
|
||||
irqc->irq_set_wake = NULL;
|
||||
}
|
||||
if (bank->is_mpuio && !bank->regs->wkup_en)
|
||||
irqc->irq_set_wake = NULL;
|
||||
|
||||
irq = &bank->chip.irq;
|
||||
irq->chip = irqc;
|
||||
@@ -1215,7 +1055,7 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
||||
|
||||
static void omap_gpio_init_context(struct gpio_bank *p)
|
||||
{
|
||||
struct omap_gpio_reg_offs *regs = p->regs;
|
||||
const struct omap_gpio_reg_offs *regs = p->regs;
|
||||
void __iomem *base = p->base;
|
||||
|
||||
p->context.ctrl = readl_relaxed(base + regs->ctrl);
|
||||
@@ -1227,60 +1067,56 @@ static void omap_gpio_init_context(struct gpio_bank *p)
|
||||
p->context.fallingdetect = readl_relaxed(base + regs->fallingdetect);
|
||||
p->context.irqenable1 = readl_relaxed(base + regs->irqenable);
|
||||
p->context.irqenable2 = readl_relaxed(base + regs->irqenable2);
|
||||
|
||||
if (regs->set_dataout && p->regs->clr_dataout)
|
||||
p->context.dataout = readl_relaxed(base + regs->set_dataout);
|
||||
else
|
||||
p->context.dataout = readl_relaxed(base + regs->dataout);
|
||||
p->context.dataout = readl_relaxed(base + regs->dataout);
|
||||
|
||||
p->context_valid = true;
|
||||
}
|
||||
|
||||
static void omap_gpio_restore_context(struct gpio_bank *bank)
|
||||
{
|
||||
writel_relaxed(bank->context.wake_en,
|
||||
bank->base + bank->regs->wkup_en);
|
||||
writel_relaxed(bank->context.ctrl, bank->base + bank->regs->ctrl);
|
||||
writel_relaxed(bank->context.leveldetect0,
|
||||
bank->base + bank->regs->leveldetect0);
|
||||
writel_relaxed(bank->context.leveldetect1,
|
||||
bank->base + bank->regs->leveldetect1);
|
||||
writel_relaxed(bank->context.risingdetect,
|
||||
bank->base + bank->regs->risingdetect);
|
||||
writel_relaxed(bank->context.fallingdetect,
|
||||
bank->base + bank->regs->fallingdetect);
|
||||
if (bank->regs->set_dataout && bank->regs->clr_dataout)
|
||||
writel_relaxed(bank->context.dataout,
|
||||
bank->base + bank->regs->set_dataout);
|
||||
else
|
||||
writel_relaxed(bank->context.dataout,
|
||||
bank->base + bank->regs->dataout);
|
||||
writel_relaxed(bank->context.oe, bank->base + bank->regs->direction);
|
||||
const struct omap_gpio_reg_offs *regs = bank->regs;
|
||||
void __iomem *base = bank->base;
|
||||
|
||||
writel_relaxed(bank->context.wake_en, base + regs->wkup_en);
|
||||
writel_relaxed(bank->context.ctrl, base + regs->ctrl);
|
||||
writel_relaxed(bank->context.leveldetect0, base + regs->leveldetect0);
|
||||
writel_relaxed(bank->context.leveldetect1, base + regs->leveldetect1);
|
||||
writel_relaxed(bank->context.risingdetect, base + regs->risingdetect);
|
||||
writel_relaxed(bank->context.fallingdetect, base + regs->fallingdetect);
|
||||
writel_relaxed(bank->context.dataout, base + regs->dataout);
|
||||
writel_relaxed(bank->context.oe, base + regs->direction);
|
||||
|
||||
if (bank->dbck_enable_mask) {
|
||||
writel_relaxed(bank->context.debounce, bank->base +
|
||||
bank->regs->debounce);
|
||||
writel_relaxed(bank->context.debounce, base + regs->debounce);
|
||||
writel_relaxed(bank->context.debounce_en,
|
||||
bank->base + bank->regs->debounce_en);
|
||||
base + regs->debounce_en);
|
||||
}
|
||||
|
||||
writel_relaxed(bank->context.irqenable1,
|
||||
bank->base + bank->regs->irqenable);
|
||||
writel_relaxed(bank->context.irqenable2,
|
||||
bank->base + bank->regs->irqenable2);
|
||||
writel_relaxed(bank->context.irqenable1, base + regs->irqenable);
|
||||
writel_relaxed(bank->context.irqenable2, base + regs->irqenable2);
|
||||
}
|
||||
|
||||
static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context)
|
||||
{
|
||||
struct device *dev = bank->chip.parent;
|
||||
void __iomem *base = bank->base;
|
||||
u32 nowake;
|
||||
u32 mask, nowake;
|
||||
|
||||
bank->saved_datain = readl_relaxed(base + bank->regs->datain);
|
||||
|
||||
if (!bank->enabled_non_wakeup_gpios)
|
||||
goto update_gpio_context_count;
|
||||
|
||||
/* Check for pending EDGE_FALLING, ignore EDGE_BOTH */
|
||||
mask = bank->enabled_non_wakeup_gpios & bank->context.fallingdetect;
|
||||
mask &= ~bank->context.risingdetect;
|
||||
bank->saved_datain |= mask;
|
||||
|
||||
/* Check for pending EDGE_RISING, ignore EDGE_BOTH */
|
||||
mask = bank->enabled_non_wakeup_gpios & bank->context.risingdetect;
|
||||
mask &= ~bank->context.fallingdetect;
|
||||
bank->saved_datain &= ~mask;
|
||||
|
||||
if (!may_lose_context)
|
||||
goto update_gpio_context_count;
|
||||
|
||||
@@ -1291,8 +1127,8 @@ static void omap_gpio_idle(struct gpio_bank *bank, bool may_lose_context)
|
||||
*/
|
||||
if (!bank->loses_context && bank->enabled_non_wakeup_gpios) {
|
||||
nowake = bank->enabled_non_wakeup_gpios;
|
||||
omap_gpio_rmw(base, bank->regs->fallingdetect, nowake, ~nowake);
|
||||
omap_gpio_rmw(base, bank->regs->risingdetect, nowake, ~nowake);
|
||||
omap_gpio_rmw(base + bank->regs->fallingdetect, nowake, ~nowake);
|
||||
omap_gpio_rmw(base + bank->regs->risingdetect, nowake, ~nowake);
|
||||
}
|
||||
|
||||
update_gpio_context_count:
|
||||
@@ -1421,7 +1257,7 @@ static int gpio_omap_cpu_notifier(struct notifier_block *nb,
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct omap_gpio_reg_offs omap2_gpio_regs = {
|
||||
static const struct omap_gpio_reg_offs omap2_gpio_regs = {
|
||||
.revision = OMAP24XX_GPIO_REVISION,
|
||||
.direction = OMAP24XX_GPIO_OE,
|
||||
.datain = OMAP24XX_GPIO_DATAIN,
|
||||
@@ -1444,7 +1280,7 @@ static struct omap_gpio_reg_offs omap2_gpio_regs = {
|
||||
.fallingdetect = OMAP24XX_GPIO_FALLINGDETECT,
|
||||
};
|
||||
|
||||
static struct omap_gpio_reg_offs omap4_gpio_regs = {
|
||||
static const struct omap_gpio_reg_offs omap4_gpio_regs = {
|
||||
.revision = OMAP4_GPIO_REVISION,
|
||||
.direction = OMAP4_GPIO_OE,
|
||||
.datain = OMAP4_GPIO_DATAIN,
|
||||
@@ -1453,6 +1289,8 @@ static struct omap_gpio_reg_offs omap4_gpio_regs = {
|
||||
.clr_dataout = OMAP4_GPIO_CLEARDATAOUT,
|
||||
.irqstatus = OMAP4_GPIO_IRQSTATUS0,
|
||||
.irqstatus2 = OMAP4_GPIO_IRQSTATUS1,
|
||||
.irqstatus_raw0 = OMAP4_GPIO_IRQSTATUSRAW0,
|
||||
.irqstatus_raw1 = OMAP4_GPIO_IRQSTATUSRAW1,
|
||||
.irqenable = OMAP4_GPIO_IRQSTATUSSET0,
|
||||
.irqenable2 = OMAP4_GPIO_IRQSTATUSSET1,
|
||||
.set_irqenable = OMAP4_GPIO_IRQSTATUSSET0,
|
||||
@@ -1528,7 +1366,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
irqc->irq_startup = omap_gpio_irq_startup,
|
||||
irqc->irq_shutdown = omap_gpio_irq_shutdown,
|
||||
irqc->irq_ack = omap_gpio_ack_irq,
|
||||
irqc->irq_ack = dummy_irq_chip.irq_ack,
|
||||
irqc->irq_mask = omap_gpio_mask_irq,
|
||||
irqc->irq_unmask = omap_gpio_unmask_irq,
|
||||
irqc->irq_set_type = omap_gpio_irq_type,
|
||||
@@ -1572,14 +1410,10 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
||||
pdata->get_context_loss_count;
|
||||
}
|
||||
|
||||
if (bank->regs->set_dataout && bank->regs->clr_dataout) {
|
||||
if (bank->regs->set_dataout && bank->regs->clr_dataout)
|
||||
bank->set_dataout = omap_set_gpio_dataout_reg;
|
||||
bank->set_dataout_multiple = omap_set_gpio_dataout_reg_multiple;
|
||||
} else {
|
||||
else
|
||||
bank->set_dataout = omap_set_gpio_dataout_mask;
|
||||
bank->set_dataout_multiple =
|
||||
omap_set_gpio_dataout_mask_multiple;
|
||||
}
|
||||
|
||||
raw_spin_lock_init(&bank->lock);
|
||||
raw_spin_lock_init(&bank->wa_lock);
|
||||
@@ -1635,7 +1469,6 @@ static int omap_gpio_remove(struct platform_device *pdev)
|
||||
struct gpio_bank *bank = platform_get_drvdata(pdev);
|
||||
|
||||
cpu_pm_unregister_notifier(&bank->nb);
|
||||
list_del(&bank->node);
|
||||
gpiochip_remove(&bank->chip);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
if (bank->dbck_flag)
|
||||
|
@@ -1178,6 +1178,7 @@ static const struct of_device_id pca953x_dt_ids[] = {
|
||||
{ .compatible = "ti,tca6408", .data = OF_953X( 8, PCA_INT), },
|
||||
{ .compatible = "ti,tca6416", .data = OF_953X(16, PCA_INT), },
|
||||
{ .compatible = "ti,tca6424", .data = OF_953X(24, PCA_INT), },
|
||||
{ .compatible = "ti,tca9539", .data = OF_953X(16, PCA_INT), },
|
||||
|
||||
{ .compatible = "onnn,cat9554", .data = OF_953X( 8, PCA_INT), },
|
||||
{ .compatible = "onnn,pca9654", .data = OF_953X( 8, PCA_INT), },
|
||||
|
@@ -283,6 +283,7 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
{
|
||||
struct device *dev = &adev->dev;
|
||||
struct pl061 *pl061;
|
||||
struct gpio_irq_chip *girq;
|
||||
int ret, irq;
|
||||
|
||||
pl061 = devm_kzalloc(dev, sizeof(*pl061), GFP_KERNEL);
|
||||
@@ -310,10 +311,6 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
pl061->gc.parent = dev;
|
||||
pl061->gc.owner = THIS_MODULE;
|
||||
|
||||
ret = gpiochip_add_data(&pl061->gc, pl061);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* irq_chip support
|
||||
*/
|
||||
@@ -332,19 +329,24 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
}
|
||||
pl061->parent_irq = irq;
|
||||
|
||||
ret = gpiochip_irqchip_add(&pl061->gc, &pl061->irq_chip,
|
||||
0, handle_bad_irq,
|
||||
IRQ_TYPE_NONE);
|
||||
if (ret) {
|
||||
dev_info(&adev->dev, "could not add irqchip\n");
|
||||
girq = &pl061->gc.irq;
|
||||
girq->chip = &pl061->irq_chip;
|
||||
girq->parent_handler = pl061_irq_handler;
|
||||
girq->num_parents = 1;
|
||||
girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
|
||||
GFP_KERNEL);
|
||||
if (!girq->parents)
|
||||
return -ENOMEM;
|
||||
girq->parents[0] = irq;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_bad_irq;
|
||||
|
||||
ret = devm_gpiochip_add_data(dev, &pl061->gc, pl061);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
gpiochip_set_chained_irqchip(&pl061->gc, &pl061->irq_chip,
|
||||
irq, pl061_irq_handler);
|
||||
|
||||
amba_set_drvdata(adev, pl061);
|
||||
dev_info(&adev->dev, "PL061 GPIO chip @%pa registered\n",
|
||||
&adev->res.start);
|
||||
dev_info(dev, "PL061 GPIO chip registered\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -489,7 +489,7 @@ static int gpio_rcar_probe(struct platform_device *pdev)
|
||||
irq_chip->irq_unmask = gpio_rcar_irq_enable;
|
||||
irq_chip->irq_set_type = gpio_rcar_irq_set_type;
|
||||
irq_chip->irq_set_wake = gpio_rcar_irq_set_wake;
|
||||
irq_chip->flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND;
|
||||
irq_chip->flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND;
|
||||
|
||||
ret = gpiochip_add_data(gpio_chip, p);
|
||||
if (ret) {
|
||||
|
@@ -211,20 +211,22 @@ static int gpio_siox_get_direction(struct gpio_chip *chip, unsigned int offset)
|
||||
static int gpio_siox_probe(struct siox_device *sdevice)
|
||||
{
|
||||
struct gpio_siox_ddata *ddata;
|
||||
struct gpio_irq_chip *girq;
|
||||
struct device *dev = &sdevice->dev;
|
||||
int ret;
|
||||
|
||||
ddata = devm_kzalloc(&sdevice->dev, sizeof(*ddata), GFP_KERNEL);
|
||||
ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
|
||||
if (!ddata)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(&sdevice->dev, ddata);
|
||||
dev_set_drvdata(dev, ddata);
|
||||
|
||||
mutex_init(&ddata->lock);
|
||||
spin_lock_init(&ddata->irqlock);
|
||||
|
||||
ddata->gchip.base = -1;
|
||||
ddata->gchip.can_sleep = 1;
|
||||
ddata->gchip.parent = &sdevice->dev;
|
||||
ddata->gchip.parent = dev;
|
||||
ddata->gchip.owner = THIS_MODULE;
|
||||
ddata->gchip.get = gpio_siox_get;
|
||||
ddata->gchip.set = gpio_siox_set;
|
||||
@@ -239,54 +241,27 @@ static int gpio_siox_probe(struct siox_device *sdevice)
|
||||
ddata->ichip.irq_unmask = gpio_siox_irq_unmask;
|
||||
ddata->ichip.irq_set_type = gpio_siox_irq_set_type;
|
||||
|
||||
ret = gpiochip_add(&ddata->gchip);
|
||||
if (ret) {
|
||||
dev_err(&sdevice->dev,
|
||||
"Failed to register gpio chip (%d)\n", ret);
|
||||
goto err_gpiochip;
|
||||
}
|
||||
girq = &ddata->gchip.irq;
|
||||
girq->chip = &ddata->ichip;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_level_irq;
|
||||
|
||||
ret = gpiochip_irqchip_add(&ddata->gchip, &ddata->ichip,
|
||||
0, handle_level_irq, IRQ_TYPE_EDGE_RISING);
|
||||
if (ret) {
|
||||
dev_err(&sdevice->dev,
|
||||
"Failed to register irq chip (%d)\n", ret);
|
||||
err_gpiochip:
|
||||
gpiochip_remove(&ddata->gchip);
|
||||
}
|
||||
ret = devm_gpiochip_add_data(dev, &ddata->gchip, NULL);
|
||||
if (ret)
|
||||
dev_err(dev, "Failed to register gpio chip (%d)\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gpio_siox_remove(struct siox_device *sdevice)
|
||||
{
|
||||
struct gpio_siox_ddata *ddata = dev_get_drvdata(&sdevice->dev);
|
||||
|
||||
gpiochip_remove(&ddata->gchip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct siox_driver gpio_siox_driver = {
|
||||
.probe = gpio_siox_probe,
|
||||
.remove = gpio_siox_remove,
|
||||
.set_data = gpio_siox_set_data,
|
||||
.get_data = gpio_siox_get_data,
|
||||
.driver = {
|
||||
.name = "gpio-siox",
|
||||
},
|
||||
};
|
||||
|
||||
static int __init gpio_siox_init(void)
|
||||
{
|
||||
return siox_driver_register(&gpio_siox_driver);
|
||||
}
|
||||
module_init(gpio_siox_init);
|
||||
|
||||
static void __exit gpio_siox_exit(void)
|
||||
{
|
||||
siox_driver_unregister(&gpio_siox_driver);
|
||||
}
|
||||
module_exit(gpio_siox_exit);
|
||||
module_siox_driver(gpio_siox_driver);
|
||||
|
||||
MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
|
||||
MODULE_DESCRIPTION("SIOX gpio driver");
|
||||
|
@@ -15,8 +15,6 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
|
||||
/*
|
||||
* The Serial To Parallel (STP) is found on MIPS based Lantiq socs. It is a
|
||||
* peripheral controller used to drive external shift register cascades. At most
|
||||
@@ -71,8 +69,7 @@
|
||||
#define xway_stp_r32(m, reg) __raw_readl(m + reg)
|
||||
#define xway_stp_w32(m, val, reg) __raw_writel(val, m + reg)
|
||||
#define xway_stp_w32_mask(m, clear, set, reg) \
|
||||
ltq_w32((ltq_r32(m + reg) & ~(clear)) | (set), \
|
||||
m + reg)
|
||||
xway_stp_w32(m, (xway_stp_r32(m, reg) & ~(clear)) | (set), reg)
|
||||
|
||||
struct xway_stp {
|
||||
struct gpio_chip gc;
|
||||
@@ -156,9 +153,9 @@ static int xway_stp_request(struct gpio_chip *gc, unsigned gpio)
|
||||
|
||||
/**
|
||||
* xway_stp_hw_init() - Configure the STP unit and enable the clock gate
|
||||
* @virt: pointer to the remapped register range
|
||||
* @chip: Pointer to the xway_stp chip structure
|
||||
*/
|
||||
static int xway_stp_hw_init(struct xway_stp *chip)
|
||||
static void xway_stp_hw_init(struct xway_stp *chip)
|
||||
{
|
||||
/* sane defaults */
|
||||
xway_stp_w32(chip->virt, 0, XWAY_STP_AR);
|
||||
@@ -201,8 +198,6 @@ static int xway_stp_hw_init(struct xway_stp *chip)
|
||||
if (chip->reserved)
|
||||
xway_stp_w32_mask(chip->virt, XWAY_STP_UPD_MASK,
|
||||
XWAY_STP_UPD_FPI, XWAY_STP_CON1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xway_stp_probe(struct platform_device *pdev)
|
||||
@@ -258,21 +253,27 @@ static int xway_stp_probe(struct platform_device *pdev)
|
||||
if (!of_find_property(pdev->dev.of_node, "lantiq,rising", NULL))
|
||||
chip->edge = XWAY_STP_FALLING;
|
||||
|
||||
clk = clk_get(&pdev->dev, NULL);
|
||||
clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(clk)) {
|
||||
dev_err(&pdev->dev, "Failed to get clock\n");
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
clk_enable(clk);
|
||||
|
||||
ret = xway_stp_hw_init(chip);
|
||||
if (!ret)
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, &chip->gc, chip);
|
||||
ret = clk_prepare_enable(clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!ret)
|
||||
dev_info(&pdev->dev, "Init done\n");
|
||||
xway_stp_hw_init(chip);
|
||||
|
||||
return ret;
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, &chip->gc, chip);
|
||||
if (ret) {
|
||||
clk_disable_unprepare(clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "Init done\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id xway_stp_match[] = {
|
||||
|
@@ -541,8 +541,8 @@ DEFINE_SHOW_ATTRIBUTE(tegra_dbg_gpio);
|
||||
|
||||
static void tegra_gpio_debuginit(struct tegra_gpio_info *tgi)
|
||||
{
|
||||
(void) debugfs_create_file("tegra_gpio", 0444,
|
||||
NULL, tgi, &tegra_dbg_gpio_fops);
|
||||
debugfs_create_file("tegra_gpio", 0444, NULL, tgi,
|
||||
&tegra_dbg_gpio_fops);
|
||||
}
|
||||
|
||||
#else
|
||||
|
@@ -265,7 +265,8 @@ static int vf610_gpio_probe(struct platform_device *pdev)
|
||||
return port->irq;
|
||||
|
||||
port->clk_port = devm_clk_get(dev, "port");
|
||||
if (!IS_ERR(port->clk_port)) {
|
||||
ret = PTR_ERR_OR_ZERO(port->clk_port);
|
||||
if (!ret) {
|
||||
ret = clk_prepare_enable(port->clk_port);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -273,16 +274,17 @@ static int vf610_gpio_probe(struct platform_device *pdev)
|
||||
port->clk_port);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else if (port->clk_port == ERR_PTR(-EPROBE_DEFER)) {
|
||||
} else if (ret == -EPROBE_DEFER) {
|
||||
/*
|
||||
* Percolate deferrals, for anything else,
|
||||
* just live without the clocking.
|
||||
*/
|
||||
return PTR_ERR(port->clk_port);
|
||||
return ret;
|
||||
}
|
||||
|
||||
port->clk_gpio = devm_clk_get(dev, "gpio");
|
||||
if (!IS_ERR(port->clk_gpio)) {
|
||||
ret = PTR_ERR_OR_ZERO(port->clk_gpio);
|
||||
if (!ret) {
|
||||
ret = clk_prepare_enable(port->clk_gpio);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -290,8 +292,8 @@ static int vf610_gpio_probe(struct platform_device *pdev)
|
||||
port->clk_gpio);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else if (port->clk_gpio == ERR_PTR(-EPROBE_DEFER)) {
|
||||
return PTR_ERR(port->clk_gpio);
|
||||
} else if (ret == -EPROBE_DEFER) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
gc = &port->gc;
|
||||
|
@@ -467,10 +467,9 @@ static struct gpio_chip vr41xx_gpio_chip = {
|
||||
|
||||
static int giu_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
unsigned int trigger, i, pin;
|
||||
struct irq_chip *chip;
|
||||
int irq, ret;
|
||||
int irq;
|
||||
|
||||
switch (pdev->id) {
|
||||
case GPIO_50PINS_PULLUPDOWN:
|
||||
@@ -489,21 +488,14 @@ static int giu_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -EBUSY;
|
||||
|
||||
giu_base = ioremap(res->start, resource_size(res));
|
||||
if (!giu_base)
|
||||
return -ENOMEM;
|
||||
giu_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(giu_base))
|
||||
return PTR_ERR(giu_base);
|
||||
|
||||
vr41xx_gpio_chip.parent = &pdev->dev;
|
||||
|
||||
ret = gpiochip_add_data(&vr41xx_gpio_chip, NULL);
|
||||
if (!ret) {
|
||||
iounmap(giu_base);
|
||||
if (gpiochip_add_data(&vr41xx_gpio_chip, NULL))
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
giu_write(GIUINTENL, 0);
|
||||
giu_write(GIUINTENH, 0);
|
||||
@@ -534,7 +526,6 @@ static int giu_probe(struct platform_device *pdev)
|
||||
static int giu_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (giu_base) {
|
||||
iounmap(giu_base);
|
||||
giu_base = NULL;
|
||||
}
|
||||
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -33,14 +32,16 @@
|
||||
|
||||
/**
|
||||
* struct xgpio_instance - Stores information about GPIO device
|
||||
* @mmchip: OF GPIO chip for memory mapped banks
|
||||
* @gc: GPIO chip
|
||||
* @regs: register block
|
||||
* @gpio_width: GPIO width for every channel
|
||||
* @gpio_state: GPIO state shadow register
|
||||
* @gpio_dir: GPIO direction shadow register
|
||||
* @gpio_lock: Lock used for synchronization
|
||||
*/
|
||||
struct xgpio_instance {
|
||||
struct of_mm_gpio_chip mmchip;
|
||||
struct gpio_chip gc;
|
||||
void __iomem *regs;
|
||||
unsigned int gpio_width[2];
|
||||
u32 gpio_state[2];
|
||||
u32 gpio_dir[2];
|
||||
@@ -84,11 +85,10 @@ static inline int xgpio_offset(struct xgpio_instance *chip, int gpio)
|
||||
*/
|
||||
static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
|
||||
{
|
||||
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
||||
struct xgpio_instance *chip = gpiochip_get_data(gc);
|
||||
u32 val;
|
||||
|
||||
val = xgpio_readreg(mm_gc->regs + XGPIO_DATA_OFFSET +
|
||||
val = xgpio_readreg(chip->regs + XGPIO_DATA_OFFSET +
|
||||
xgpio_regoffset(chip, gpio));
|
||||
|
||||
return !!(val & BIT(xgpio_offset(chip, gpio)));
|
||||
@@ -106,7 +106,6 @@ static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
|
||||
static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
||||
struct xgpio_instance *chip = gpiochip_get_data(gc);
|
||||
int index = xgpio_index(chip, gpio);
|
||||
int offset = xgpio_offset(chip, gpio);
|
||||
@@ -119,7 +118,7 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
else
|
||||
chip->gpio_state[index] &= ~BIT(offset);
|
||||
|
||||
xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
|
||||
xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
|
||||
xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
|
||||
|
||||
spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
|
||||
@@ -138,7 +137,6 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
|
||||
unsigned long *bits)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
||||
struct xgpio_instance *chip = gpiochip_get_data(gc);
|
||||
int index = xgpio_index(chip, 0);
|
||||
int offset, i;
|
||||
@@ -150,7 +148,7 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
|
||||
if (*mask == 0)
|
||||
break;
|
||||
if (index != xgpio_index(chip, i)) {
|
||||
xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
|
||||
xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
|
||||
xgpio_regoffset(chip, i),
|
||||
chip->gpio_state[index]);
|
||||
spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
|
||||
@@ -166,7 +164,7 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
|
||||
}
|
||||
}
|
||||
|
||||
xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
|
||||
xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
|
||||
xgpio_regoffset(chip, i), chip->gpio_state[index]);
|
||||
|
||||
spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
|
||||
@@ -184,7 +182,6 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
|
||||
static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
||||
struct xgpio_instance *chip = gpiochip_get_data(gc);
|
||||
int index = xgpio_index(chip, gpio);
|
||||
int offset = xgpio_offset(chip, gpio);
|
||||
@@ -193,7 +190,7 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
|
||||
|
||||
/* Set the GPIO bit in shadow register and set direction as input */
|
||||
chip->gpio_dir[index] |= BIT(offset);
|
||||
xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET +
|
||||
xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET +
|
||||
xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
|
||||
|
||||
spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
|
||||
@@ -216,7 +213,6 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
|
||||
static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
||||
struct xgpio_instance *chip = gpiochip_get_data(gc);
|
||||
int index = xgpio_index(chip, gpio);
|
||||
int offset = xgpio_offset(chip, gpio);
|
||||
@@ -228,12 +224,12 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
chip->gpio_state[index] |= BIT(offset);
|
||||
else
|
||||
chip->gpio_state[index] &= ~BIT(offset);
|
||||
xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET +
|
||||
xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
|
||||
xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
|
||||
|
||||
/* Clear the GPIO bit in shadow register and set direction as output */
|
||||
chip->gpio_dir[index] &= ~BIT(offset);
|
||||
xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET +
|
||||
xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET +
|
||||
xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
|
||||
|
||||
spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
|
||||
@@ -243,42 +239,22 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
|
||||
/**
|
||||
* xgpio_save_regs - Set initial values of GPIO pins
|
||||
* @mm_gc: Pointer to memory mapped GPIO chip structure
|
||||
* @chip: Pointer to GPIO instance
|
||||
*/
|
||||
static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
|
||||
static void xgpio_save_regs(struct xgpio_instance *chip)
|
||||
{
|
||||
struct xgpio_instance *chip =
|
||||
container_of(mm_gc, struct xgpio_instance, mmchip);
|
||||
|
||||
xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state[0]);
|
||||
xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir[0]);
|
||||
xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET, chip->gpio_state[0]);
|
||||
xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET, chip->gpio_dir[0]);
|
||||
|
||||
if (!chip->gpio_width[1])
|
||||
return;
|
||||
|
||||
xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET + XGPIO_CHANNEL_OFFSET,
|
||||
xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET + XGPIO_CHANNEL_OFFSET,
|
||||
chip->gpio_state[1]);
|
||||
xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET + XGPIO_CHANNEL_OFFSET,
|
||||
xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET + XGPIO_CHANNEL_OFFSET,
|
||||
chip->gpio_dir[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* xgpio_remove - Remove method for the GPIO device.
|
||||
* @pdev: pointer to the platform device
|
||||
*
|
||||
* This function remove gpiochips and frees all the allocated resources.
|
||||
*
|
||||
* Return: 0 always
|
||||
*/
|
||||
static int xgpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct xgpio_instance *chip = platform_get_drvdata(pdev);
|
||||
|
||||
of_mm_gpiochip_remove(&chip->mmchip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* xgpio_of_probe - Probe method for the GPIO device.
|
||||
* @pdev: pointer to the platform device
|
||||
@@ -340,21 +316,28 @@ static int xgpio_probe(struct platform_device *pdev)
|
||||
spin_lock_init(&chip->gpio_lock[1]);
|
||||
}
|
||||
|
||||
chip->mmchip.gc.ngpio = chip->gpio_width[0] + chip->gpio_width[1];
|
||||
chip->mmchip.gc.parent = &pdev->dev;
|
||||
chip->mmchip.gc.direction_input = xgpio_dir_in;
|
||||
chip->mmchip.gc.direction_output = xgpio_dir_out;
|
||||
chip->mmchip.gc.get = xgpio_get;
|
||||
chip->mmchip.gc.set = xgpio_set;
|
||||
chip->mmchip.gc.set_multiple = xgpio_set_multiple;
|
||||
chip->gc.base = -1;
|
||||
chip->gc.ngpio = chip->gpio_width[0] + chip->gpio_width[1];
|
||||
chip->gc.parent = &pdev->dev;
|
||||
chip->gc.direction_input = xgpio_dir_in;
|
||||
chip->gc.direction_output = xgpio_dir_out;
|
||||
chip->gc.get = xgpio_get;
|
||||
chip->gc.set = xgpio_set;
|
||||
chip->gc.set_multiple = xgpio_set_multiple;
|
||||
|
||||
chip->mmchip.save_regs = xgpio_save_regs;
|
||||
chip->gc.label = dev_name(&pdev->dev);
|
||||
|
||||
/* Call the OF gpio helper to setup and register the GPIO device */
|
||||
status = of_mm_gpiochip_add_data(np, &chip->mmchip, chip);
|
||||
chip->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(chip->regs)) {
|
||||
dev_err(&pdev->dev, "failed to ioremap memory resource\n");
|
||||
return PTR_ERR(chip->regs);
|
||||
}
|
||||
|
||||
xgpio_save_regs(chip);
|
||||
|
||||
status = devm_gpiochip_add_data(&pdev->dev, &chip->gc, chip);
|
||||
if (status) {
|
||||
pr_err("%pOF: error in probe function with status %d\n",
|
||||
np, status);
|
||||
dev_err(&pdev->dev, "failed to add GPIO chip\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -370,7 +353,6 @@ MODULE_DEVICE_TABLE(of, xgpio_of_match);
|
||||
|
||||
static struct platform_driver xgpio_plat_driver = {
|
||||
.probe = xgpio_probe,
|
||||
.remove = xgpio_remove,
|
||||
.driver = {
|
||||
.name = "gpio-xilinx",
|
||||
.of_match_table = xgpio_of_match,
|
||||
|
@@ -217,14 +217,13 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
|
||||
if (!handler)
|
||||
return AE_OK;
|
||||
|
||||
desc = gpiochip_request_own_desc(chip, pin, "ACPI:Event", 0);
|
||||
desc = gpiochip_request_own_desc(chip, pin, "ACPI:Event",
|
||||
GPIO_ACTIVE_HIGH, GPIOD_IN);
|
||||
if (IS_ERR(desc)) {
|
||||
dev_err(chip->parent, "Failed to request GPIO\n");
|
||||
return AE_ERROR;
|
||||
}
|
||||
|
||||
gpiod_direction_input(desc);
|
||||
|
||||
ret = gpiochip_lock_as_irq(chip, pin);
|
||||
if (ret) {
|
||||
dev_err(chip->parent, "Failed to lock GPIO as interrupt\n");
|
||||
@@ -951,6 +950,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
|
||||
const char *label = "ACPI:OpRegion";
|
||||
|
||||
desc = gpiochip_request_own_desc(chip, pin, label,
|
||||
GPIO_ACTIVE_HIGH,
|
||||
flags);
|
||||
if (IS_ERR(desc)) {
|
||||
status = AE_ERROR;
|
||||
|
@@ -165,6 +165,12 @@ static void of_gpio_flags_quirks(struct device_node *np,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Legacy handling of stmmac's active-low PHY reset line */
|
||||
if (IS_ENABLED(CONFIG_STMMAC_ETH) &&
|
||||
!strcmp(propname, "snps,reset-gpio") &&
|
||||
of_property_read_bool(np, "snps,reset-active-low"))
|
||||
*flags |= OF_GPIO_ACTIVE_LOW;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -261,6 +267,37 @@ static struct gpio_desc *of_find_spi_gpio(struct device *dev, const char *con_id
|
||||
return desc;
|
||||
}
|
||||
|
||||
/*
|
||||
* The old Freescale bindings use simply "gpios" as name for the chip select
|
||||
* lines rather than "cs-gpios" like all other SPI hardware. Account for this
|
||||
* with a special quirk.
|
||||
*/
|
||||
static struct gpio_desc *of_find_spi_cs_gpio(struct device *dev,
|
||||
const char *con_id,
|
||||
unsigned int idx,
|
||||
unsigned long *flags)
|
||||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_SPI_MASTER))
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
/* Allow this specifically for Freescale devices */
|
||||
if (!of_device_is_compatible(np, "fsl,spi") &&
|
||||
!of_device_is_compatible(np, "aeroflexgaisler,spictrl"))
|
||||
return ERR_PTR(-ENOENT);
|
||||
/* Allow only if asking for "cs-gpios" */
|
||||
if (!con_id || strcmp(con_id, "cs"))
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
/*
|
||||
* While all other SPI controllers use "cs-gpios" the Freescale
|
||||
* uses just "gpios" so translate to that when "cs-gpios" is
|
||||
* requested.
|
||||
*/
|
||||
return of_find_gpio(dev, NULL, idx, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some regulator bindings happened before we managed to establish that GPIO
|
||||
* properties should be named "foo-gpios" so we have this special kludge for
|
||||
@@ -332,6 +369,12 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
|
||||
/* Special handling for SPI GPIOs if used */
|
||||
if (IS_ERR(desc))
|
||||
desc = of_find_spi_gpio(dev, con_id, &of_flags);
|
||||
if (IS_ERR(desc)) {
|
||||
/* This quirk looks up flags and all */
|
||||
desc = of_find_spi_cs_gpio(dev, con_id, idx, flags);
|
||||
if (!IS_ERR(desc))
|
||||
return desc;
|
||||
}
|
||||
|
||||
/* Special handling for regulator GPIOs if used */
|
||||
if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER)
|
||||
|
@@ -1644,39 +1644,47 @@ EXPORT_SYMBOL_GPL(gpiochip_irqchip_irq_valid);
|
||||
|
||||
/**
|
||||
* gpiochip_set_cascaded_irqchip() - connects a cascaded irqchip to a gpiochip
|
||||
* @gpiochip: the gpiochip to set the irqchip chain to
|
||||
* @gc: the gpiochip to set the irqchip chain to
|
||||
* @parent_irq: the irq number corresponding to the parent IRQ for this
|
||||
* chained irqchip
|
||||
* @parent_handler: the parent interrupt handler for the accumulated IRQ
|
||||
* coming out of the gpiochip. If the interrupt is nested rather than
|
||||
* cascaded, pass NULL in this handler argument
|
||||
*/
|
||||
static void gpiochip_set_cascaded_irqchip(struct gpio_chip *gpiochip,
|
||||
static void gpiochip_set_cascaded_irqchip(struct gpio_chip *gc,
|
||||
unsigned int parent_irq,
|
||||
irq_flow_handler_t parent_handler)
|
||||
{
|
||||
if (!gpiochip->irq.domain) {
|
||||
chip_err(gpiochip, "called %s before setting up irqchip\n",
|
||||
struct gpio_irq_chip *girq = &gc->irq;
|
||||
struct device *dev = &gc->gpiodev->dev;
|
||||
|
||||
if (!girq->domain) {
|
||||
chip_err(gc, "called %s before setting up irqchip\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent_handler) {
|
||||
if (gpiochip->can_sleep) {
|
||||
chip_err(gpiochip,
|
||||
if (gc->can_sleep) {
|
||||
chip_err(gc,
|
||||
"you cannot have chained interrupts on a chip that may sleep\n");
|
||||
return;
|
||||
}
|
||||
girq->parents = devm_kcalloc(dev, 1,
|
||||
sizeof(*girq->parents),
|
||||
GFP_KERNEL);
|
||||
if (!girq->parents) {
|
||||
chip_err(gc, "out of memory allocating parent IRQ\n");
|
||||
return;
|
||||
}
|
||||
girq->parents[0] = parent_irq;
|
||||
girq->num_parents = 1;
|
||||
/*
|
||||
* The parent irqchip is already using the chip_data for this
|
||||
* irqchip, so our callbacks simply use the handler_data.
|
||||
*/
|
||||
irq_set_chained_handler_and_data(parent_irq, parent_handler,
|
||||
gpiochip);
|
||||
|
||||
gpiochip->irq.parent_irq = parent_irq;
|
||||
gpiochip->irq.parents = &gpiochip->irq.parent_irq;
|
||||
gpiochip->irq.num_parents = 1;
|
||||
gc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2503,7 +2511,11 @@ EXPORT_SYMBOL_GPL(gpiochip_is_requested);
|
||||
* @chip: GPIO chip
|
||||
* @hwnum: hardware number of the GPIO for which to request the descriptor
|
||||
* @label: label for the GPIO
|
||||
* @flags: flags for this GPIO or 0 if default
|
||||
* @lflags: lookup flags for this GPIO or 0 if default, this can be used to
|
||||
* specify things like line inversion semantics with the machine flags
|
||||
* such as GPIO_OUT_LOW
|
||||
* @dflags: descriptor request flags for this GPIO or 0 if default, this
|
||||
* can be used to specify consumer semantics such as open drain
|
||||
*
|
||||
* Function allows GPIO chip drivers to request and use their own GPIO
|
||||
* descriptors via gpiolib API. Difference to gpiod_request() is that this
|
||||
@@ -2517,9 +2529,9 @@ EXPORT_SYMBOL_GPL(gpiochip_is_requested);
|
||||
*/
|
||||
struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *chip, u16 hwnum,
|
||||
const char *label,
|
||||
enum gpiod_flags flags)
|
||||
enum gpio_lookup_flags lflags,
|
||||
enum gpiod_flags dflags)
|
||||
{
|
||||
unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT;
|
||||
struct gpio_desc *desc = gpiochip_get_desc(chip, hwnum);
|
||||
int err;
|
||||
|
||||
@@ -2532,7 +2544,7 @@ struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *chip, u16 hwnum,
|
||||
if (err < 0)
|
||||
return ERR_PTR(err);
|
||||
|
||||
err = gpiod_configure_flags(desc, label, lflags, flags);
|
||||
err = gpiod_configure_flags(desc, label, lflags, dflags);
|
||||
if (err) {
|
||||
chip_err(chip, "setup of own GPIO %s failed\n", label);
|
||||
gpiod_free_commit(desc);
|
||||
@@ -3019,13 +3031,13 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
|
||||
* Return the GPIO's raw value, i.e. the value of the physical line disregarding
|
||||
* its ACTIVE_LOW status, or negative errno on failure.
|
||||
*
|
||||
* This function should be called from contexts where we cannot sleep, and will
|
||||
* This function can be called from contexts where we cannot sleep, and will
|
||||
* complain if the GPIO chip functions potentially sleep.
|
||||
*/
|
||||
int gpiod_get_raw_value(const struct gpio_desc *desc)
|
||||
{
|
||||
VALIDATE_DESC(desc);
|
||||
/* Should be using gpio_get_value_cansleep() */
|
||||
/* Should be using gpiod_get_raw_value_cansleep() */
|
||||
WARN_ON(desc->gdev->chip->can_sleep);
|
||||
return gpiod_get_raw_value_commit(desc);
|
||||
}
|
||||
@@ -3038,7 +3050,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_raw_value);
|
||||
* Return the GPIO's logical value, i.e. taking the ACTIVE_LOW status into
|
||||
* account, or negative errno on failure.
|
||||
*
|
||||
* This function should be called from contexts where we cannot sleep, and will
|
||||
* This function can be called from contexts where we cannot sleep, and will
|
||||
* complain if the GPIO chip functions potentially sleep.
|
||||
*/
|
||||
int gpiod_get_value(const struct gpio_desc *desc)
|
||||
@@ -3046,7 +3058,7 @@ int gpiod_get_value(const struct gpio_desc *desc)
|
||||
int value;
|
||||
|
||||
VALIDATE_DESC(desc);
|
||||
/* Should be using gpio_get_value_cansleep() */
|
||||
/* Should be using gpiod_get_value_cansleep() */
|
||||
WARN_ON(desc->gdev->chip->can_sleep);
|
||||
|
||||
value = gpiod_get_raw_value_commit(desc);
|
||||
@@ -3071,7 +3083,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_value);
|
||||
* without regard for their ACTIVE_LOW status. Return 0 in case of success,
|
||||
* else an error code.
|
||||
*
|
||||
* This function should be called from contexts where we cannot sleep,
|
||||
* This function can be called from contexts where we cannot sleep,
|
||||
* and it will complain if the GPIO chip functions potentially sleep.
|
||||
*/
|
||||
int gpiod_get_raw_array_value(unsigned int array_size,
|
||||
@@ -3097,7 +3109,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_raw_array_value);
|
||||
* Read the logical values of the GPIOs, i.e. taking their ACTIVE_LOW status
|
||||
* into account. Return 0 in case of success, else an error code.
|
||||
*
|
||||
* This function should be called from contexts where we cannot sleep,
|
||||
* This function can be called from contexts where we cannot sleep,
|
||||
* and it will complain if the GPIO chip functions potentially sleep.
|
||||
*/
|
||||
int gpiod_get_array_value(unsigned int array_size,
|
||||
@@ -3311,13 +3323,13 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
|
||||
* Set the raw value of the GPIO, i.e. the value of its physical line without
|
||||
* regard for its ACTIVE_LOW status.
|
||||
*
|
||||
* This function should be called from contexts where we cannot sleep, and will
|
||||
* This function can be called from contexts where we cannot sleep, and will
|
||||
* complain if the GPIO chip functions potentially sleep.
|
||||
*/
|
||||
void gpiod_set_raw_value(struct gpio_desc *desc, int value)
|
||||
{
|
||||
VALIDATE_DESC_VOID(desc);
|
||||
/* Should be using gpiod_set_value_cansleep() */
|
||||
/* Should be using gpiod_set_raw_value_cansleep() */
|
||||
WARN_ON(desc->gdev->chip->can_sleep);
|
||||
gpiod_set_raw_value_commit(desc, value);
|
||||
}
|
||||
@@ -3352,12 +3364,13 @@ static void gpiod_set_value_nocheck(struct gpio_desc *desc, int value)
|
||||
* Set the logical value of the GPIO, i.e. taking its ACTIVE_LOW,
|
||||
* OPEN_DRAIN and OPEN_SOURCE flags into account.
|
||||
*
|
||||
* This function should be called from contexts where we cannot sleep, and will
|
||||
* This function can be called from contexts where we cannot sleep, and will
|
||||
* complain if the GPIO chip functions potentially sleep.
|
||||
*/
|
||||
void gpiod_set_value(struct gpio_desc *desc, int value)
|
||||
{
|
||||
VALIDATE_DESC_VOID(desc);
|
||||
/* Should be using gpiod_set_value_cansleep() */
|
||||
WARN_ON(desc->gdev->chip->can_sleep);
|
||||
gpiod_set_value_nocheck(desc, value);
|
||||
}
|
||||
@@ -3373,7 +3386,7 @@ EXPORT_SYMBOL_GPL(gpiod_set_value);
|
||||
* Set the raw values of the GPIOs, i.e. the values of the physical lines
|
||||
* without regard for their ACTIVE_LOW status.
|
||||
*
|
||||
* This function should be called from contexts where we cannot sleep, and will
|
||||
* This function can be called from contexts where we cannot sleep, and will
|
||||
* complain if the GPIO chip functions potentially sleep.
|
||||
*/
|
||||
int gpiod_set_raw_array_value(unsigned int array_size,
|
||||
@@ -3398,7 +3411,7 @@ EXPORT_SYMBOL_GPL(gpiod_set_raw_array_value);
|
||||
* Set the logical values of the GPIOs, i.e. taking their ACTIVE_LOW status
|
||||
* into account.
|
||||
*
|
||||
* This function should be called from contexts where we cannot sleep, and will
|
||||
* This function can be called from contexts where we cannot sleep, and will
|
||||
* complain if the GPIO chip functions potentially sleep.
|
||||
*/
|
||||
int gpiod_set_array_value(unsigned int array_size,
|
||||
@@ -4420,15 +4433,8 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
|
||||
chip = gpiod_to_chip(desc);
|
||||
hwnum = gpio_chip_hwgpio(desc);
|
||||
|
||||
/*
|
||||
* FIXME: not very elegant that we call gpiod_configure_flags()
|
||||
* twice here (once inside gpiochip_request_own_desc() and
|
||||
* again here), but the gpiochip_request_own_desc() is external
|
||||
* and cannot really pass the lflags so this is the lesser evil
|
||||
* at the moment. Pass zero as dflags on this first call so we
|
||||
* don't screw anything up.
|
||||
*/
|
||||
local_desc = gpiochip_request_own_desc(chip, hwnum, name, 0);
|
||||
local_desc = gpiochip_request_own_desc(chip, hwnum, name,
|
||||
lflags, dflags);
|
||||
if (IS_ERR(local_desc)) {
|
||||
status = PTR_ERR(local_desc);
|
||||
pr_err("requesting hog GPIO %s (chip %s, offset %d) failed, %d\n",
|
||||
@@ -4436,14 +4442,6 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
|
||||
return status;
|
||||
}
|
||||
|
||||
status = gpiod_configure_flags(desc, name, lflags, dflags);
|
||||
if (status < 0) {
|
||||
pr_err("setup of hog GPIO %s (chip %s, offset %d) failed, %d\n",
|
||||
name, chip->label, hwnum, status);
|
||||
gpiochip_free_own_desc(desc);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Mark GPIO as hogged so it can be identified and removed later */
|
||||
set_bit(FLAG_IS_HOGGED, &desc->flags);
|
||||
|
||||
@@ -4805,8 +4803,8 @@ static const struct file_operations gpiolib_operations = {
|
||||
static int __init gpiolib_debugfs_init(void)
|
||||
{
|
||||
/* /sys/kernel/debug/gpio */
|
||||
(void) debugfs_create_file("gpio", S_IFREG | S_IRUGO,
|
||||
NULL, NULL, &gpiolib_operations);
|
||||
debugfs_create_file("gpio", S_IFREG | S_IRUGO, NULL, NULL,
|
||||
&gpiolib_operations);
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(gpiolib_debugfs_init);
|
||||
|
@@ -210,7 +210,7 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
|
||||
struct gpio_array *array_info,
|
||||
unsigned long *value_bitmap);
|
||||
|
||||
extern struct spinlock gpio_lock;
|
||||
extern spinlock_t gpio_lock;
|
||||
extern struct list_head gpio_devices;
|
||||
|
||||
struct gpio_desc {
|
||||
|
Reference in New Issue
Block a user