Commit 3c2edc36 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pinctrl-v5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pin control updates from Linus Walleij:
 "This is the bulk of pin control changes for the v5.4 kernel cycle:

  Core changes:

   - Fix errors in example code in the documentation.

  New drivers:

   - Add support for JZ4760, JZ4760B, X1000, X1000E and X1500 to the
     Ingenic driver.

   - Support Cirrus Logic Madera CS47L92 and CS47L15.

   - Support Allwinner Sunxi V3S.

   - Support Aspeed 2600 BMC.

   - Support Qualcomm SC7180.

   - Support Marvell MVEBU CS115.

  Driver improvements:

   - Clean up a few drivers to use the devm_platform_ioremap_resource()
     helper.

   - Pass the irqchip when registering the gpio_chip in some pin
     controllers that are also GPIO controllers.

   - Support suspend/resume in the Tegra driver.

   - Support pull-up on the Broadcom BCM2711.

   - The Intel driver can now request locked pads.

   - Fix the UFS reset pin in the Qualcomm SDM845 driver"

* tag 'pinctrl-v5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (112 commits)
  pinctrl: meson-gxbb: Fix wrong pinning definition for uart_c
  pinctrl: sh-pfc: Unlock on error in sh_pfc_func_set_mux()
  pinctrl: bcm: remove redundant assignment to pointer log
  pinctrl: iproc: Add 'get_direction' support
  pinctrl: iproc-gpio: Handle interrupts for multiple instances
  pinctrl: iproc-gpio: Fix incorrect pinconf configurations
  pinctrl: intel: mark intel_pin_to_gpio __maybe_unused
  pinctrl: qcom: sdm845: Fix UFS_RESET pin
  pinctrl: mvebu: add additional variant for standalone CP115
  pinctrl: mvebu: Add CP110 missing pin functionality
  dt-bindings: cp110: document the new CP115 pinctrl compatible
  pinctrl: bcm2835: Pass irqchip when adding gpiochip
  pinctrl: meson: meson: Add of_node_put() before return
  pinctrl/gpio: Take MUX usage into account
  dt-bindings: pinctrl: qcom-pmic-gpio: Add pm8150l support
  dt-bindings: pinctrl: qcom-pmic-gpio: Add pm8150b support
  dt-bindings: pinctrl: qcom-pmic-gpio: Add pm8150 support
  pinctrl: amd: disable spurious-firing GPIO IRQs
  pinctrl: rza2: Include the appropriate headers
  pinctrl: rza2: Drop driver use of consumer flags
  ...
parents 32b90daf cb0438e4
......@@ -78,8 +78,8 @@ Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt.
Required properties:
- compatible: "marvell,armada-7k-pinctrl",
"marvell,armada-8k-cpm-pinctrl" or "marvell,armada-8k-cps-pinctrl"
- compatible: "marvell,armada-7k-pinctrl", "marvell,armada-8k-cpm-pinctrl",
"marvell,armada-8k-cps-pinctrl" or "marvell,cp115-standalone-pinctrl"
depending on the specific variant of the SoC being used.
Available mpp pins/groups and functions:
......
......@@ -4,9 +4,7 @@ configuring elements such as clocks, pinmux, and reset.
Required properties:
- compatible: One of:
"aspeed,ast2400-scu", "syscon", "simple-mfd"
"aspeed,g4-scu", "syscon", "simple-mfd"
"aspeed,ast2500-scu", "syscon", "simple-mfd"
"aspeed,g5-scu", "syscon", "simple-mfd"
- reg: contains the offset and length of the SCU memory region
- #clock-cells: should be set to <1> - the system controller is also a
......
......@@ -26,9 +26,7 @@ property:
- compatible : Should be one of the following:
"aspeed,ast2400-scu", "syscon", "simple-mfd"
"aspeed,g4-scu", "syscon", "simple-mfd"
"aspeed,ast2500-scu", "syscon", "simple-mfd"
"aspeed,g5-scu", "syscon", "simple-mfd"
Example
===================
......
......@@ -15,16 +15,13 @@ description: |+
- compatible: Should be one of the following:
"aspeed,ast2400-scu", "syscon", "simple-mfd"
"aspeed,g4-scu", "syscon", "simple-mfd"
Refer to the the bindings described in
Documentation/devicetree/bindings/mfd/syscon.txt
properties:
compatible:
enum:
- aspeed,ast2400-pinctrl
- aspeed,g4-pinctrl
const: aspeed,ast2400-pinctrl
patternProperties:
'^.*$':
......@@ -35,28 +32,24 @@ patternProperties:
"^function|groups$":
allOf:
- $ref: "/schemas/types.yaml#/definitions/string"
- enum: [ "ACPI", "ADC0", "ADC1", "ADC10", "ADC11", "ADC12", "ADC13",
"ADC14", "ADC15", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6", "ADC7",
"ADC8", "ADC9", "BMCINT", "DDCCLK", "DDCDAT", "EXTRST", "FLACK",
"FLBUSY", "FLWP", "GPID", "GPID0", "GPID2", "GPID4", "GPID6",
"GPIE0", "GPIE2", "GPIE4", "GPIE6", "I2C10", "I2C11", "I2C12",
"I2C13", "I2C14", "I2C3", "I2C4", "I2C5", "I2C6", "I2C7", "I2C8",
"I2C9", "LPCPD", "LPCPME", "LPCRST", "LPCSMI", "MAC1LINK",
"MAC2LINK", "MDIO1", "MDIO2", "NCTS1", "NCTS2", "NCTS3", "NCTS4",
"NDCD1", "NDCD2", "NDCD3", "NDCD4", "NDSR1", "NDSR2", "NDSR3",
"NDSR4", "NDTR1", "NDTR2", "NDTR3", "NDTR4", "NDTS4", "NRI1",
"NRI2", "NRI3", "NRI4", "NRTS1", "NRTS2", "NRTS3", "OSCCLK",
"PWM0", "PWM1", "PWM2", "PWM3", "PWM4", "PWM5", "PWM6", "PWM7",
"RGMII1", "RGMII2", "RMII1", "RMII2", "ROM16", "ROM8", "ROMCS1",
"ROMCS2", "ROMCS3", "ROMCS4", "RXD1", "RXD2", "RXD3", "RXD4",
"SALT1", "SALT2", "SALT3", "SALT4", "SD1", "SD2", "SGPMCK",
"SGPMI", "SGPMLD", "SGPMO", "SGPSCK", "SGPSI0", "SGPSI1", "SGPSLD",
"SIOONCTRL", "SIOPBI", "SIOPBO", "SIOPWREQ", "SIOPWRGD", "SIOS3",
"SIOS5", "SIOSCI", "SPI1", "SPI1DEBUG", "SPI1PASSTHRU", "SPICS1",
"TIMER3", "TIMER4", "TIMER5", "TIMER6", "TIMER7", "TIMER8", "TXD1",
"TXD2", "TXD3", "TXD4", "UART6", "USB11D1", "USB11H2", "USB2D1",
"USB2H1", "USBCKI", "VGABIOS_ROM", "VGAHS", "VGAVS", "VPI18",
"VPI24", "VPI30", "VPO12", "VPO24", "WDTRST1", "WDTRST2" ]
- enum: [ ACPI, ADC0, ADC1, ADC10, ADC11, ADC12, ADC13, ADC14,
ADC15, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT,
DDCCLK, DDCDAT, EXTRST, FLACK, FLBUSY, FLWP, GPID, GPID0, GPID2,
GPID4, GPID6, GPIE0, GPIE2, GPIE4, GPIE6, I2C10, I2C11, I2C12,
I2C13, I2C14, I2C3, I2C4, I2C5, I2C6, I2C7, I2C8, I2C9, LPCPD,
LPCPME, LPCRST, LPCSMI, MAC1LINK, MAC2LINK, MDIO1, MDIO2, NCTS1,
NCTS2, NCTS3, NCTS4, NDCD1, NDCD2, NDCD3, NDCD4, NDSR1, NDSR2,
NDSR3, NDSR4, NDTR1, NDTR2, NDTR3, NDTR4, NDTS4, NRI1, NRI2,
NRI3, NRI4, NRTS1, NRTS2, NRTS3, OSCCLK, PWM0, PWM1, PWM2, PWM3,
PWM4, PWM5, PWM6, PWM7, RGMII1, RGMII2, RMII1, RMII2, ROM16,
ROM8, ROMCS1, ROMCS2, ROMCS3, ROMCS4, RXD1, RXD2, RXD3, RXD4,
SALT1, SALT2, SALT3, SALT4, SD1, SD2, SGPMCK, SGPMI, SGPMLD,
SGPMO, SGPSCK, SGPSI0, SGPSI1, SGPSLD, SIOONCTRL, SIOPBI, SIOPBO,
SIOPWREQ, SIOPWRGD, SIOS3, SIOS5, SIOSCI, SPI1, SPI1DEBUG,
SPI1PASSTHRU, SPICS1, TIMER3, TIMER4, TIMER5, TIMER6, TIMER7,
TIMER8, TXD1, TXD2, TXD3, TXD4, UART6, USB11D1, USB11H2, USB2D1,
USB2H1, USBCKI, VGABIOS_ROM, VGAHS, VGAVS, VPI18, VPI24, VPI30,
VPO12, VPO24, WDTRST1, WDTRST2 ]
required:
- compatible
......
......@@ -22,9 +22,7 @@ description: |+
properties:
compatible:
enum:
- aspeed,ast2500-pinctrl
- aspeed,g5-pinctrl
const: aspeed,ast2500-pinctrl
aspeed,external-nodes:
minItems: 2
maxItems: 2
......@@ -44,31 +42,26 @@ patternProperties:
"^function|groups$":
allOf:
- $ref: "/schemas/types.yaml#/definitions/string"
- enum: [ "ACPI", "ADC0", "ADC1", "ADC10", "ADC11", "ADC12", "ADC13",
"ADC14", "ADC15", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6", "ADC7",
"ADC8", "ADC9", "BMCINT", "DDCCLK", "DDCDAT", "ESPI", "FWSPICS1",
"FWSPICS2", "GPID0", "GPID2", "GPID4", "GPID6", "GPIE0", "GPIE2",
"GPIE4", "GPIE6", "I2C10", "I2C11", "I2C12", "I2C13", "I2C14",
"I2C3", "I2C4", "I2C5", "I2C6", "I2C7", "I2C8", "I2C9", "LAD0",
"LAD1", "LAD2", "LAD3", "LCLK", "LFRAME", "LPCHC", "LPCPD",
"LPCPLUS", "LPCPME", "LPCRST", "LPCSMI", "LSIRQ", "MAC1LINK",
"MAC2LINK", "MDIO1", "MDIO2", "NCTS1", "NCTS2", "NCTS3", "NCTS4",
"NDCD1", "NDCD2", "NDCD3", "NDCD4", "NDSR1", "NDSR2", "NDSR3",
"NDSR4", "NDTR1", "NDTR2", "NDTR3", "NDTR4", "NRI1", "NRI2",
"NRI3", "NRI4", "NRTS1", "NRTS2", "NRTS3", "NRTS4", "OSCCLK",
"PEWAKE", "PNOR", "PWM0", "PWM1", "PWM2", "PWM3", "PWM4", "PWM5",
"PWM6", "PWM7", "RGMII1", "RGMII2", "RMII1", "RMII2", "RXD1",
"RXD2", "RXD3", "RXD4", "SALT1", "SALT10", "SALT11", "SALT12",
"SALT13", "SALT14", "SALT2", "SALT3", "SALT4", "SALT5", "SALT6",
"SALT7", "SALT8", "SALT9", "SCL1", "SCL2", "SD1", "SD2", "SDA1",
"SDA2", "SGPS1", "SGPS2", "SIOONCTRL", "SIOPBI", "SIOPBO",
"SIOPWREQ", "SIOPWRGD", "SIOS3", "SIOS5", "SIOSCI", "SPI1",
"SPI1CS1", "SPI1DEBUG", "SPI1PASSTHRU", "SPI2CK", "SPI2CS0",
"SPI2CS1", "SPI2MISO", "SPI2MOSI", "TIMER3", "TIMER4", "TIMER5",
"TIMER6", "TIMER7", "TIMER8", "TXD1", "TXD2", "TXD3", "TXD4",
"UART6", "USB11BHID", "USB2AD", "USB2AH", "USB2BD", "USB2BH",
"USBCKI", "VGABIOSROM", "VGAHS", "VGAVS", "VPI24", "VPO",
"WDTRST1", "WDTRST2", ]
- enum: [ ACPI, ADC0, ADC1, ADC10, ADC11, ADC12, ADC13, ADC14,
ADC15, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT,
DDCCLK, DDCDAT, ESPI, FWSPICS1, FWSPICS2, GPID0, GPID2, GPID4,
GPID6, GPIE0, GPIE2, GPIE4, GPIE6, I2C10, I2C11, I2C12, I2C13,
I2C14, I2C3, I2C4, I2C5, I2C6, I2C7, I2C8, I2C9, LAD0, LAD1,
LAD2, LAD3, LCLK, LFRAME, LPCHC, LPCPD, LPCPLUS, LPCPME, LPCRST,
LPCSMI, LSIRQ, MAC1LINK, MAC2LINK, MDIO1, MDIO2, NCTS1, NCTS2,
NCTS3, NCTS4, NDCD1, NDCD2, NDCD3, NDCD4, NDSR1, NDSR2, NDSR3,
NDSR4, NDTR1, NDTR2, NDTR3, NDTR4, NRI1, NRI2, NRI3, NRI4, NRTS1,
NRTS2, NRTS3, NRTS4, OSCCLK, PEWAKE, PNOR, PWM0, PWM1, PWM2,
PWM3, PWM4, PWM5, PWM6, PWM7, RGMII1, RGMII2, RMII1, RMII2, RXD1,
RXD2, RXD3, RXD4, SALT1, SALT10, SALT11, SALT12, SALT13, SALT14,
SALT2, SALT3, SALT4, SALT5, SALT6, SALT7, SALT8, SALT9, SCL1,
SCL2, SD1, SD2, SDA1, SDA2, SGPS1, SGPS2, SIOONCTRL, SIOPBI,
SIOPBO, SIOPWREQ, SIOPWRGD, SIOS3, SIOS5, SIOSCI, SPI1, SPI1CS1,
SPI1DEBUG, SPI1PASSTHRU, SPI2CK, SPI2CS0, SPI2CS1, SPI2MISO,
SPI2MOSI, TIMER3, TIMER4, TIMER5, TIMER6, TIMER7, TIMER8, TXD1,
TXD2, TXD3, TXD4, UART6, USB11BHID, USB2AD, USB2AH, USB2BD,
USB2BH, USBCKI, VGABIOSROM, VGAHS, VGAVS, VPI24, VPO, WDTRST1,
WDTRST2, ]
required:
- compatible
......
# SPDX-License-Identifier: GPL-2.0+
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/aspeed,ast2600-pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ASPEED AST2600 Pin Controller
maintainers:
- Andrew Jeffery <andrew@aj.id.au>
description: |+
The pin controller node should be the child of a syscon node with the
required property:
- compatible: Should be one of the following:
"aspeed,ast2600-scu", "syscon", "simple-mfd"
Refer to the the bindings described in
Documentation/devicetree/bindings/mfd/syscon.txt
properties:
compatible:
const: aspeed,ast2600-pinctrl
patternProperties:
'^.*$':
if:
type: object
then:
properties:
function:
allOf:
- $ref: "/schemas/types.yaml#/definitions/string"
- enum: [ ADC0, ADC1, ADC10, ADC11, ADC12, ADC13, ADC14, ADC15,
ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT, ESPI,
ESPIALT, FSI1, FSI2, FWSPIABR, FWSPID, FWSPIWP, GPIT0, GPIT1,
GPIT2, GPIT3, GPIT4, GPIT5, GPIT6, GPIT7, GPIU0, GPIU1, GPIU2,
GPIU3, GPIU4, GPIU5, GPIU6, GPIU7, I2C1, I2C10, I2C11, I2C12,
I2C13, I2C14, I2C15, I2C16, I2C2, I2C3, I2C4, I2C5, I2C6, I2C7,
I2C8, I2C9, I3C3, I3C4, I3C5, I3C6, JTAGM, LHPD, LHSIRQ, LPC,
LPCHC, LPCPD, LPCPME, LPCSMI, LSIRQ, MACLINK1, MACLINK2,
MACLINK3, MACLINK4, MDIO1, MDIO2, MDIO3, MDIO4, NCTS1, NCTS2,
NCTS3, NCTS4, NDCD1, NDCD2, NDCD3, NDCD4, NDSR1, NDSR2, NDSR3,
NDSR4, NDTR1, NDTR2, NDTR3, NDTR4, NRI1, NRI2, NRI3, NRI4, NRTS1,
NRTS2, NRTS3, NRTS4, OSCCLK, PEWAKE, PWM0, PWM1, PWM10, PWM11,
PWM12, PWM13, PWM14, PWM15, PWM2, PWM3, PWM4, PWM5, PWM6, PWM7,
PWM8, PWM9, RGMII1, RGMII2, RGMII3, RGMII4, RMII1, RMII2, RMII3,
RMII4, RXD1, RXD2, RXD3, RXD4, SALT1, SALT10, SALT11, SALT12,
SALT13, SALT14, SALT15, SALT16, SALT2, SALT3, SALT4, SALT5,
SALT6, SALT7, SALT8, SALT9, SD1, SD2, SD3, SD3DAT4, SD3DAT5,
SD3DAT6, SD3DAT7, SGPM1, SGPS1, SIOONCTRL, SIOPBI, SIOPBO,
SIOPWREQ, SIOPWRGD, SIOS3, SIOS5, SIOSCI, SPI1, SPI1ABR, SPI1CS1,
SPI1WP, SPI2, SPI2CS1, SPI2CS2, TACH0, TACH1, TACH10, TACH11,
TACH12, TACH13, TACH14, TACH15, TACH2, TACH3, TACH4, TACH5,
TACH6, TACH7, TACH8, TACH9, THRU0, THRU1, THRU2, THRU3, TXD1,
TXD2, TXD3, TXD4, UART10, UART11, UART12, UART13, UART6, UART7,
UART8, UART9, VB, VGAHS, VGAVS, WDTRST1, WDTRST2, WDTRST3,
WDTRST4, ]
groups:
allOf:
- $ref: "/schemas/types.yaml#/definitions/string"
- enum: [ ADC0, ADC1, ADC10, ADC11, ADC12, ADC13, ADC14, ADC15,
ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT, ESPI,
ESPIALT, FSI1, FSI2, FWSPIABR, FWSPID, FWQSPID, FWSPIWP, GPIT0,
GPIT1, GPIT2, GPIT3, GPIT4, GPIT5, GPIT6, GPIT7, GPIU0, GPIU1,
GPIU2, GPIU3, GPIU4, GPIU5, GPIU6, GPIU7, HVI3C3, HVI3C4, I2C1,
I2C10, I2C11, I2C12, I2C13, I2C14, I2C15, I2C16, I2C2, I2C3,
I2C4, I2C5, I2C6, I2C7, I2C8, I2C9, I3C3, I3C4, I3C5, I3C6,
JTAGM, LHPD, LHSIRQ, LPC, LPCHC, LPCPD, LPCPME, LPCSMI, LSIRQ,
MACLINK1, MACLINK2, MACLINK3, MACLINK4, MDIO1, MDIO2, MDIO3,
MDIO4, NCTS1, NCTS2, NCTS3, NCTS4, NDCD1, NDCD2, NDCD3, NDCD4,
NDSR1, NDSR2, NDSR3, NDSR4, NDTR1, NDTR2, NDTR3, NDTR4, NRI1,
NRI2, NRI3, NRI4, NRTS1, NRTS2, NRTS3, NRTS4, OSCCLK, PEWAKE,
PWM0, PWM1, PWM10G0, PWM10G1, PWM11G0, PWM11G1, PWM12G0, PWM12G1,
PWM13G0, PWM13G1, PWM14G0, PWM14G1, PWM15G0, PWM15G1, PWM2, PWM3,
PWM4, PWM5, PWM6, PWM7, PWM8G0, PWM8G1, PWM9G0, PWM9G1, QSPI1,
QSPI2, RGMII1, RGMII2, RGMII3, RGMII4, RMII1, RMII2, RMII3,
RMII4, RXD1, RXD2, RXD3, RXD4, SALT1, SALT10G0, SALT10G1,
SALT11G0, SALT11G1, SALT12G0, SALT12G1, SALT13G0, SALT13G1,
SALT14G0, SALT14G1, SALT15G0, SALT15G1, SALT16G0, SALT16G1,
SALT2, SALT3, SALT4, SALT5, SALT6, SALT7, SALT8, SALT9G0,
SALT9G1, SD1, SD2, SD3, SD3DAT4, SD3DAT5, SD3DAT6, SD3DAT7,
SGPM1, SGPS1, SIOONCTRL, SIOPBI, SIOPBO, SIOPWREQ, SIOPWRGD,
SIOS3, SIOS5, SIOSCI, SPI1, SPI1ABR, SPI1CS1, SPI1WP, SPI2,
SPI2CS1, SPI2CS2, TACH0, TACH1, TACH10, TACH11, TACH12, TACH13,
TACH14, TACH15, TACH2, TACH3, TACH4, TACH5, TACH6, TACH7, TACH8,
TACH9, THRU0, THRU1, THRU2, THRU3, TXD1, TXD2, TXD3, TXD4,
UART10, UART11, UART12G0, UART12G1, UART13G0, UART13G1, UART6,
UART7, UART8, UART9, VB, VGAHS, VGAVS, WDTRST1, WDTRST2, WDTRST3,
WDTRST4, ]
required:
- compatible
examples:
- |
syscon: scu@1e6e2000 {
compatible = "aspeed,ast2600-scu", "syscon", "simple-mfd";
reg = <0x1e6e2000 0xf6c>;
pinctrl: pinctrl {
compatible = "aspeed,g6-pinctrl";
pinctrl_pwm10g1_default: pwm10g1_default {
function = "PWM10";
groups = "PWM10G1";
};
pinctrl_gpioh0_unbiased_default: gpioh0 {
pins = "A18";
bias-disable;
};
};
};
......@@ -8,6 +8,7 @@ Required properties:
- compatible: should be one of:
"brcm,bcm2835-gpio" - BCM2835 compatible pinctrl
"brcm,bcm7211-gpio" - BCM7211 compatible pinctrl
"brcm,bcm2711-gpio" - BCM2711 compatible pinctrl
- reg: Should contain the physical address of the GPIO module's registers.
- gpio-controller: Marks the device node as a GPIO controller.
- #gpio-cells : Should be two. The first cell is the pin number and the
......
Ingenic jz47xx pin controller
Ingenic XBurst pin controller
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
For the jz47xx SoCs, pin control is tightly bound with GPIO ports. All pins may
For the XBurst SoCs, pin control is tightly bound with GPIO ports. All pins may
be used as GPIOs, multiplexed device functions are configured within the
GPIO port configuration registers and it is typical to refer to pins using the
naming scheme "PxN" where x is a character identifying the GPIO port with
which the pin is associated and N is an integer from 0 to 31 identifying the
pin within that GPIO port. For example PA0 is the first pin in GPIO port A, and
PB31 is the last pin in GPIO port B. The jz4740 contains 4 GPIO ports, PA to
PD, for a total of 128 pins. The jz4780 contains 6 GPIO ports, PA to PF, for a
total of 192 pins.
PB31 is the last pin in GPIO port B. The jz4740 and the x1000 contains 4 GPIO
ports, PA to PD, for a total of 128 pins. The jz4760, the jz4770 and the jz4780
contains 6 GPIO ports, PA to PF, for a total of 192 pins.
Required properties:
......@@ -21,8 +21,13 @@ Required properties:
- compatible: One of:
- "ingenic,jz4740-pinctrl"
- "ingenic,jz4725b-pinctrl"
- "ingenic,jz4760-pinctrl"
- "ingenic,jz4760b-pinctrl"
- "ingenic,jz4770-pinctrl"
- "ingenic,jz4780-pinctrl"
- "ingenic,x1000-pinctrl"
- "ingenic,x1000e-pinctrl"
- "ingenic,x1500-pinctrl"
- reg: Address range of the pinctrl registers.
......@@ -31,8 +36,10 @@ Required properties for sub-nodes (GPIO chips):
- compatible: Must contain one of:
- "ingenic,jz4740-gpio"
- "ingenic,jz4760-gpio"
- "ingenic,jz4770-gpio"
- "ingenic,jz4780-gpio"
- "ingenic,x1000-gpio"
- reg: The GPIO bank number.
- interrupt-controller: Marks the device node as an interrupt controller.
- interrupts: Interrupt specifier for the controllers interrupt.
......
......@@ -132,9 +132,8 @@ to specify in a pin configuration subnode:
qlink_request, qua_mi2s, sd_card, sd_write, sdc40, sdc41,
sdc42, sdc43, sdc4_clk, sdc4_cmd, sec_mi2s, sp_cmu,
spkr_i2s, ssbi1, ssc_irq, ter_mi2s, tgu_ch0, tgu_ch1,
tsense_pwm1, tsense_pwm2, tsif1_clk, tsif1_data, tsif1_en,
tsif1_error, tsif1_sync, tsif2_clk, tsif2_data, tsif2_en,
tsif2_error, tsif2_sync, uim1_clk, uim1_data, uim1_present,
tsense_pwm1, tsense_pwm2, tsif0, tsif1,
uim1_clk, uim1_data, uim1_present,
uim1_reset, uim2_clk, uim2_data, uim2_present, uim2_reset,
uim_batt, usb_phy, vfr_1, vsense_clkout, vsense_data0,
vsense_data1, vsense_mode, wlan1_adc0, wlan1_adc1,
......
......@@ -21,6 +21,8 @@ PMIC's from Qualcomm.
"qcom,pmi8994-gpio"
"qcom,pmi8998-gpio"
"qcom,pms405-gpio"
"qcom,pm8150-gpio"
"qcom,pm8150b-gpio"
And must contain either "qcom,spmi-gpio" or "qcom,ssbi-gpio"
if the device is on an spmi bus or an ssbi bus respectively
......@@ -94,6 +96,10 @@ to specify in a pin configuration subnode:
gpio1-gpio22 for pma8084
gpio1-gpio10 for pmi8994
gpio1-gpio12 for pms405 (holes on gpio1, gpio9 and gpio10)
gpio1-gpio10 for pm8150 (holes on gpio2, gpio5, gpio7
and gpio8)
gpio1-gpio12 for pm8150b (holes on gpio3, gpio4, gpio7)
gpio1-gpio12 for pm8150l (hole on gpio7)
- function:
Usage: required
......
Qualcomm Technologies, Inc. SC7180 TLMM block
This binding describes the Top Level Mode Multiplexer block found in the
SC7180 platform.
- compatible:
Usage: required
Value type: <string>
Definition: must be "qcom,sc7180-pinctrl"
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: the base address and size of the north, south and west
TLMM tiles
- reg-names:
Usage: required
Value type: <prop-encoded-array>
Definition: names for the cells of reg, must contain "north", "south"
and "west".
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: should specify the TLMM summary IRQ.
- interrupt-controller:
Usage: required
Value type: <none>
Definition: identifies this node as an interrupt controller
- #interrupt-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/interrupt-controller/irq.h>
- gpio-controller:
Usage: required
Value type: <none>
Definition: identifies this node as a gpio controller
- #gpio-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/gpio/gpio.h>
- gpio-ranges:
Usage: required
Value type: <prop-encoded-array>
Definition: see ../gpio/gpio.txt
- gpio-reserved-ranges:
Usage: optional
Value type: <prop-encoded-array>
Definition: see ../gpio/gpio.txt
Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
a general description of GPIO and interrupt bindings.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
The pin configuration nodes act as a container for an arbitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin, a group, or a list of pins or groups. This configuration can include the
mux function to select on those pin(s)/group(s), and various pin configuration
parameters, such as pull-up, drive strength, etc.
PIN CONFIGURATION NODES:
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Each subnode only affects those parameters that are explicitly listed. In
other words, a subnode that lists a mux function but no pin configuration
parameters implies no information about any pin configuration parameters.
Similarly, a pin subnode that describes a pullup parameter implies no
information about e.g. the mux function.
The following generic properties as defined in pinctrl-bindings.txt are valid
to specify in a pin configuration subnode:
- pins:
Usage: required
Value type: <string-array>
Definition: List of gpio pins affected by the properties specified in
this subnode.
Valid pins are:
gpio0-gpio118
Supports mux, bias and drive-strength
sdc1_clk, sdc1_cmd, sdc1_data sdc2_clk, sdc2_cmd,
sdc2_data sdc1_rclk
Supports bias and drive-strength
ufs_reset
Supports bias and drive-strength
- function:
Usage: required
Value type: <string>
Definition: Specify the alternative function to be configured for the
specified pins. Functions are only valid for gpio pins.
Valid values are:
adsp_ext, agera_pll, aoss_cti, atest_char, atest_char0,
atest_char1, atest_char2, atest_char3, atest_tsens,
atest_tsens2, atest_usb1, atest_usb10, atest_usb11,
atest_usb12, atest_usb13, atest_usb2, atest_usb20,
atest_usb21, atest_usb22, atest_usb23, audio_ref,
btfm_slimbus, cam_mclk, cci_async, cci_i2c, cci_timer0,
cci_timer1, cci_timer2, cci_timer3, cci_timer4,
cri_trng, dbg_out, ddr_bist, ddr_pxi0, ddr_pxi1,
ddr_pxi2, ddr_pxi3, dp_hot, edp_lcd, gcc_gp1, gcc_gp2,
gcc_gp3, gpio, gp_pdm0, gp_pdm1, gp_pdm2, gps_tx,
jitter_bist, ldo_en, ldo_update, lpass_ext, mdp_vsync,
mdp_vsync0, mdp_vsync1, mdp_vsync2, mdp_vsync3, mi2s_0,
mi2s_1, mi2s_2, mss_lte, m_voc, pa_indicator, phase_flag,
PLL_BIST, pll_bypassnl, pll_reset, prng_rosc, qdss,
qdss_cti, qlink_enable, qlink_request, qspi_clk, qspi_cs,
qspi_data, qup00, qup01, qup02, qup03, qup04, qup05,
qup10, qup11, qup12, qup13, qup14, qup15, sdc1_tb,
sdc2_tb, sd_write, sp_cmu, tgu_ch0, tgu_ch1, tgu_ch2,
tgu_ch3, tsense_pwm1, tsense_pwm2, uim1, uim2, uim_batt,
usb_phy, vfr_1, _V_GPIO, _V_PPS_IN, _V_PPS_OUT,
vsense_trigger, wlan1_adc0, wlan1_adc1, wlan2_adc0,
wlan2_adc1,
- bias-disable:
Usage: optional
Value type: <none>
Definition: The specified pins should be configured as no pull.
- bias-pull-down:
Usage: optional
Value type: <none>
Definition: The specified pins should be configured as pull down.
- bias-pull-up:
Usage: optional
Value type: <none>
Definition: The specified pins should be configured as pull up.
- output-high:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
high.
Not valid for sdc pins.
- output-low:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
low.
Not valid for sdc pins.
- drive-strength:
Usage: optional
Value type: <u32>
Definition: Selects the drive strength for the specified pins, in mA.
Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16
Example:
tlmm: pinctrl@3500000 {
compatible = "qcom,sc7180-pinctrl";
reg = <0x3500000 0x300000>,
<0x3900000 0x300000>,
<0x3D00000 0x300000>;
reg-names = "west", "north", "south";
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&tlmm 0 0 119>;
gpio-reserved-ranges = <0 4>, <106 4>;
interrupt-controller;
#interrupt-cells = <2>;
};
......@@ -638,8 +638,8 @@ group of pins would work something like this::
}
static int foo_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
unsigned ** const pins,
unsigned * const num_pins)
const unsigned ** pins,
unsigned * num_pins)
{
*pins = (unsigned *) foo_groups[selector].pins;
*num_pins = foo_groups[selector].num_pins;
......@@ -705,7 +705,7 @@ group of pins would work something like this::
{
u8 regbit = (1 << selector + group);
writeb((readb(MUX)|regbit), MUX)
writeb((readb(MUX)|regbit), MUX);
return 0;
}
......
......@@ -1084,7 +1084,8 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
test_bit(FLAG_IS_HOGGED, &desc->flags) ||
test_bit(FLAG_USED_AS_IRQ, &desc->flags) ||
test_bit(FLAG_EXPORT, &desc->flags) ||
test_bit(FLAG_SYSFS, &desc->flags))
test_bit(FLAG_SYSFS, &desc->flags) ||
!pinctrl_gpio_can_use_line(chip->base + lineinfo.line_offset))
lineinfo.flags |= GPIOLINE_FLAG_KERNEL;
if (test_bit(FLAG_IS_OUT, &desc->flags))
lineinfo.flags |= GPIOLINE_FLAG_IS_OUT;
......
......@@ -23,3 +23,11 @@ config PINCTRL_ASPEED_G5
help
Say Y here to enable pin controller support for Aspeed's 5th
generation SoCs. GPIO is provided by a separate GPIO driver.
config PINCTRL_ASPEED_G6
bool "Aspeed G6 SoC pin control"
depends on (MACH_ASPEED_G6 || COMPILE_TEST) && OF
select PINCTRL_ASPEED
help
Say Y here to enable pin controller support for Aspeed's 6th
generation SoCs. GPIO is provided by a separate GPIO driver.
......@@ -5,3 +5,4 @@ ccflags-y += $(call cc-option,-Woverride-init)
obj-$(CONFIG_PINCTRL_ASPEED) += pinctrl-aspeed.o pinmux-aspeed.o
obj-$(CONFIG_PINCTRL_ASPEED_G4) += pinctrl-aspeed-g4.o
obj-$(CONFIG_PINCTRL_ASPEED_G5) += pinctrl-aspeed-g5.o
obj-$(CONFIG_PINCTRL_ASPEED_G6) += pinctrl-aspeed-g6.o
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
......@@ -57,19 +57,27 @@
#define GPAFEN0 0x88 /* Pin Async Falling Edge Detect */
#define GPPUD 0x94 /* Pin Pull-up/down Enable */
#define GPPUDCLK0 0x98 /* Pin Pull-up/down Enable Clock */
#define GP_GPIO_PUP_PDN_CNTRL_REG0 0xe4 /* 2711 Pin Pull-up/down select */
#define FSEL_REG(p) (GPFSEL0 + (((p) / 10) * 4))
#define FSEL_SHIFT(p) (((p) % 10) * 3)
#define GPIO_REG_OFFSET(p) ((p) / 32)
#define GPIO_REG_SHIFT(p) ((p) % 32)
#define PUD_2711_MASK 0x3
#define PUD_2711_REG_OFFSET(p) ((p) / 16)
#define PUD_2711_REG_SHIFT(p) (((p) % 16) * 2)
/* argument: bcm2835_pinconf_pull */
#define BCM2835_PINCONF_PARAM_PULL (PIN_CONFIG_END + 1)
#define BCM2711_PULL_NONE 0x0
#define BCM2711_PULL_UP 0x1
#define BCM2711_PULL_DOWN 0x2
struct bcm2835_pinctrl {
struct device *dev;
void __iomem *base;
int irq[BCM2835_NUM_IRQS];
/* note: locking assumes each bank will have its own unsigned long */
unsigned long enabled_irq_map[BCM2835_NUM_BANKS];
......@@ -373,14 +381,14 @@ static void bcm2835_gpio_irq_handler(struct irq_desc *desc)
int group;
int i;
for (i = 0; i < ARRAY_SIZE(pc->irq); i++) {
if (pc->irq[i] == irq) {
for (i = 0; i < BCM2835_NUM_IRQS; i++) {
if (chip->irq.parents[i] == irq) {
group = i;
break;
}
}
/* This should not happen, every IRQ has a bank */
if (i == ARRAY_SIZE(pc->irq))
if (i == BCM2835_NUM_IRQS)
BUG();
chained_irq_enter(host_chip, desc);
......@@ -975,6 +983,77 @@ static const struct pinconf_ops bcm2835_pinconf_ops = {
.pin_config_set = bcm2835_pinconf_set,
};
static void bcm2711_pull_config_set(struct bcm2835_pinctrl *pc,
unsigned int pin, unsigned int arg)
{
u32 shifter;
u32 value;
u32 off;
off = PUD_2711_REG_OFFSET(pin);
shifter = PUD_2711_REG_SHIFT(pin);
value = bcm2835_gpio_rd(pc, GP_GPIO_PUP_PDN_CNTRL_REG0 + (off * 4));
value &= ~(PUD_2711_MASK << shifter);
value |= (arg << shifter);
bcm2835_gpio_wr(pc, GP_GPIO_PUP_PDN_CNTRL_REG0 + (off * 4), value);
}
static int bcm2711_pinconf_set(struct pinctrl_dev *pctldev,
unsigned int pin, unsigned long *configs,
unsigned int num_configs)
{
struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
u32 param, arg;
int i;
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
switch (param) {
/* convert legacy brcm,pull */
case BCM2835_PINCONF_PARAM_PULL:
if (arg == BCM2835_PUD_UP)
arg = BCM2711_PULL_UP;
else if (arg == BCM2835_PUD_DOWN)
arg = BCM2711_PULL_DOWN;
else
arg = BCM2711_PULL_NONE;
bcm2711_pull_config_set(pc, pin, arg);
break;
/* Set pull generic bindings */
case PIN_CONFIG_BIAS_DISABLE:
bcm2711_pull_config_set(pc, pin, BCM2711_PULL_NONE);
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
bcm2711_pull_config_set(pc, pin, BCM2711_PULL_DOWN);
break;
case PIN_CONFIG_BIAS_PULL_UP:
bcm2711_pull_config_set(pc, pin, BCM2711_PULL_UP);
break;
/* Set output-high or output-low */
case PIN_CONFIG_OUTPUT:
bcm2835_gpio_set_bit(pc, arg ? GPSET0 : GPCLR0, pin);
break;
default:
return -ENOTSUPP;
}
} /* for each config */
return 0;
}
static const struct pinconf_ops bcm2711_pinconf_ops = {
.is_generic = true,
.pin_config_get = bcm2835_pinconf_get,
.pin_config_set = bcm2711_pinconf_set,
};
static struct pinctrl_desc bcm2835_pinctrl_desc = {
.name = MODULE_NAME,
.pins = bcm2835_gpio_pins,
......@@ -990,13 +1069,28 @@ static struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = {
.npins = BCM2835_NUM_GPIOS,
};
static const struct of_device_id bcm2835_pinctrl_match[] = {
{
.compatible = "brcm,bcm2835-gpio",
.data = &bcm2835_pinconf_ops,
},
{
.compatible = "brcm,bcm2711-gpio",
.data = &bcm2711_pinconf_ops,
},
{}
};
static int bcm2835_pinctrl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct bcm2835_pinctrl *pc;
struct gpio_irq_chip *girq;
struct resource iomem;
int err, i;
const struct of_device_id *match;
BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2835_NUM_GPIOS);
BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2835_NUM_GPIOS);
......@@ -1041,36 +1135,37 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
raw_spin_lock_init(&pc->irq_lock[i]);
}
girq = &pc->gpio_chip.irq;
girq->chip = &bcm2835_gpio_irq_chip;
girq->parent_handler = bcm2835_gpio_irq_handler;
girq->num_parents = BCM2835_NUM_IRQS;
girq->parents = devm_kcalloc(dev, BCM2835_NUM_IRQS,
sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
/*
* Use the same handler for all groups: this is necessary
* since we use one gpiochip to cover all lines - the
* irq handler then needs to figure out which group and
* bank that was firing the IRQ and look up the per-group
* and bank data.
*/
for (i = 0; i < BCM2835_NUM_IRQS; i++)
girq->parents[i] = irq_of_parse_and_map(np, i);
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;
err = gpiochip_add_data(&pc->gpio_chip, pc);
if (err) {
dev_err(dev, "could not add GPIO chip\n");
return err;
}
err = gpiochip_irqchip_add(&pc->gpio_chip, &bcm2835_gpio_irq_chip,
0, handle_level_irq, IRQ_TYPE_NONE);
if (err) {
dev_info(dev, "could not add irqchip\n");
return err;
}
for (i = 0; i < BCM2835_NUM_IRQS; i++) {
pc->irq[i] = irq_of_parse_and_map(np, i);
if (pc->irq[i] == 0)
continue;
/*
* Use the same handler for all groups: this is necessary
* since we use one gpiochip to cover all lines - the
* irq handler then needs to figure out which group and
* bank that was firing the IRQ and look up the per-group
* and bank data.
*/
gpiochip_set_chained_irqchip(&pc->gpio_chip,
&bcm2835_gpio_irq_chip,
pc->irq[i],
bcm2835_gpio_irq_handler);
match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node);
if (match) {
bcm2835_pinctrl_desc.confops =
(const struct pinconf_ops *)match->data;
}
pc->pctl_dev = devm_pinctrl_register(dev, &bcm2835_pinctrl_desc, pc);
......@@ -1087,11 +1182,6 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
return 0;
}
static const struct of_device_id bcm2835_pinctrl_match[] = {
{ .compatible = "brcm,bcm2835-gpio" },
{}
};
static struct platform_driver bcm2835_pinctrl_driver = {
.probe = bcm2835_pinctrl_probe,
.driver = {
......
......@@ -923,7 +923,6 @@ static int cygnus_mux_log_init(struct cygnus_pinctrl *pinctrl)
if (!pinctrl->mux_log)
return -ENOMEM;
log = pinctrl->mux_log;
for (i = 0; i < CYGNUS_NUM_IOMUX_REGS; i++) {
for (j = 0; j < CYGNUS_NUM_MUX_PER_REG; j++) {
log = &pinctrl->mux_log[i * CYGNUS_NUM_MUX_PER_REG
......
......@@ -54,8 +54,12 @@
/* drive strength control for ASIU GPIO */
#define IPROC_GPIO_ASIU_DRV0_CTRL_OFFSET 0x58
/* drive strength control for CCM/CRMU (AON) GPIO */
#define IPROC_GPIO_DRV0_CTRL_OFFSET 0x00
/* pinconf for CCM GPIO */
#define IPROC_GPIO_PULL_DN_OFFSET 0x10
#define IPROC_GPIO_PULL_UP_OFFSET 0x14
/* pinconf for CRMU(aon) GPIO and CCM GPIO*/
#define IPROC_GPIO_DRV_CTRL_OFFSET 0x00
#define GPIO_BANK_SIZE 0x200
#define NGPIOS_PER_BANK 32
......@@ -76,6 +80,12 @@ enum iproc_pinconf_param {
IPROC_PINCON_MAX,
};
enum iproc_pinconf_ctrl_type {
IOCTRL_TYPE_AON = 1,
IOCTRL_TYPE_CDRU,
IOCTRL_TYPE_INVALID,
};
/*
* Iproc GPIO core
*
......@@ -100,9 +110,11 @@ struct iproc_gpio {
void __iomem *base;
void __iomem *io_ctrl;
enum iproc_pinconf_ctrl_type io_ctrl_type;
raw_spinlock_t lock;
struct irq_chip irqchip;
struct gpio_chip gc;
unsigned num_banks;
......@@ -291,14 +303,6 @@ static int iproc_gpio_irq_set_type(struct irq_data *d, unsigned int type)
return 0;
}
static struct irq_chip iproc_gpio_irq_chip = {
.name = "bcm-iproc-gpio",
.irq_ack = iproc_gpio_irq_ack,
.irq_mask = iproc_gpio_irq_mask,
.irq_unmask = iproc_gpio_irq_unmask,
.irq_set_type = iproc_gpio_irq_set_type,
};
/*
* Request the Iproc IOMUX pinmux controller to mux individual pins to GPIO
*/
......@@ -355,6 +359,15 @@ static int iproc_gpio_direction_output(struct gpio_chip *gc, unsigned gpio,
return 0;
}
static int iproc_gpio_get_direction(struct gpio_chip *gc, unsigned int gpio)
{
struct iproc_gpio *chip = gpiochip_get_data(gc);
unsigned int offset = IPROC_GPIO_REG(gpio, IPROC_GPIO_OUT_EN_OFFSET);
unsigned int shift = IPROC_GPIO_SHIFT(gpio);
return !(readl(chip->base + offset) & BIT(shift));
}
static void iproc_gpio_set(struct gpio_chip *gc, unsigned gpio, int val)
{
struct iproc_gpio *chip = gpiochip_get_data(gc);
......@@ -461,20 +474,44 @@ static const struct pinctrl_ops iproc_pctrl_ops = {
static int iproc_gpio_set_pull(struct iproc_gpio *chip, unsigned gpio,
bool disable, bool pull_up)
{
void __iomem *base;
unsigned long flags;
unsigned int shift;
u32 val_1, val_2;
raw_spin_lock_irqsave(&chip->lock, flags);
if (disable) {
iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio, false);
if (chip->io_ctrl_type == IOCTRL_TYPE_CDRU) {
base = chip->io_ctrl;
shift = IPROC_GPIO_SHIFT(gpio);
val_1 = readl(base + IPROC_GPIO_PULL_UP_OFFSET);
val_2 = readl(base + IPROC_GPIO_PULL_DN_OFFSET);
if (disable) {
/* no pull-up or pull-down */
val_1 &= ~BIT(shift);
val_2 &= ~BIT(shift);
} else if (pull_up) {
val_1 |= BIT(shift);
val_2 &= ~BIT(shift);
} else {
val_1 &= ~BIT(shift);
val_2 |= BIT(shift);
}
writel(val_1, base + IPROC_GPIO_PULL_UP_OFFSET);
writel(val_2, base + IPROC_GPIO_PULL_DN_OFFSET);
} else {
iproc_set_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio,
pull_up);
iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio, true);
if (disable) {
iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio,
false);
} else {
iproc_set_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio,
pull_up);
iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio,
true);
}
}
raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set pullup:%d\n", gpio, pull_up);
return 0;
......@@ -483,14 +520,35 @@ static int iproc_gpio_set_pull(struct iproc_gpio *chip, unsigned gpio,
static void iproc_gpio_get_pull(struct iproc_gpio *chip, unsigned gpio,
bool *disable, bool *pull_up)
{
void __iomem *base;
unsigned long flags;
unsigned int shift;
u32 val_1, val_2;
raw_spin_lock_irqsave(&chip->lock, flags);
*disable = !iproc_get_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio);
*pull_up = iproc_get_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio);
if (chip->io_ctrl_type == IOCTRL_TYPE_CDRU) {
base = chip->io_ctrl;
shift = IPROC_GPIO_SHIFT(gpio);
val_1 = readl(base + IPROC_GPIO_PULL_UP_OFFSET) & BIT(shift);
val_2 = readl(base + IPROC_GPIO_PULL_DN_OFFSET) & BIT(shift);
*pull_up = val_1 ? true : false;
*disable = (val_1 | val_2) ? false : true;
} else {
*disable = !iproc_get_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio);
*pull_up = iproc_get_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio);
}
raw_spin_unlock_irqrestore(&chip->lock, flags);
}
#define DRV_STRENGTH_OFFSET(gpio, bit, type) ((type) == IOCTRL_TYPE_AON ? \
((2 - (bit)) * 4 + IPROC_GPIO_DRV_CTRL_OFFSET) : \
((type) == IOCTRL_TYPE_CDRU) ? \
((bit) * 4 + IPROC_GPIO_DRV_CTRL_OFFSET) : \
((bit) * 4 + IPROC_GPIO_REG(gpio, IPROC_GPIO_ASIU_DRV0_CTRL_OFFSET)))
static int iproc_gpio_set_strength(struct iproc_gpio *chip, unsigned gpio,
unsigned strength)
{
......@@ -505,11 +563,8 @@ static int iproc_gpio_set_strength(struct iproc_gpio *chip, unsigned gpio,
if (chip->io_ctrl) {
base = chip->io_ctrl;
offset = IPROC_GPIO_DRV0_CTRL_OFFSET;
} else {
base = chip->base;
offset = IPROC_GPIO_REG(gpio,
IPROC_GPIO_ASIU_DRV0_CTRL_OFFSET);
}
shift = IPROC_GPIO_SHIFT(gpio);
......@@ -520,11 +575,11 @@ static int iproc_gpio_set_strength(struct iproc_gpio *chip, unsigned gpio,
raw_spin_lock_irqsave(&chip->lock, flags);
strength = (strength / 2) - 1;
for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
offset = DRV_STRENGTH_OFFSET(gpio, i, chip->io_ctrl_type);
val = readl(base + offset);
val &= ~BIT(shift);
val |= ((strength >> i) & 0x1) << shift;
writel(val, base + offset);
offset += 4;
}
raw_spin_unlock_irqrestore(&chip->lock, flags);
......@@ -541,11 +596,8 @@ static int iproc_gpio_get_strength(struct iproc_gpio *chip, unsigned gpio,
if (chip->io_ctrl) {
base = chip->io_ctrl;
offset = IPROC_GPIO_DRV0_CTRL_OFFSET;
} else {
base = chip->base;
offset = IPROC_GPIO_REG(gpio,
IPROC_GPIO_ASIU_DRV0_CTRL_OFFSET);
}
shift = IPROC_GPIO_SHIFT(gpio);
......@@ -553,10 +605,10 @@ static int iproc_gpio_get_strength(struct iproc_gpio *chip, unsigned gpio,
raw_spin_lock_irqsave(&chip->lock, flags);
*strength = 0;
for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
offset = DRV_STRENGTH_OFFSET(gpio, i, chip->io_ctrl_type);
val = readl(base + offset) & BIT(shift);
val >>= shift;
*strength += (val << i);
offset += 4;
}
/* convert to mA */
......@@ -734,6 +786,7 @@ static int iproc_gpio_probe(struct platform_device *pdev)
u32 ngpios, pinconf_disable_mask = 0;
int irq, ret;
bool no_pinconf = false;
enum iproc_pinconf_ctrl_type io_ctrl_type = IOCTRL_TYPE_INVALID;
/* NSP does not support drive strength config */
if (of_device_is_compatible(dev->of_node, "brcm,iproc-nsp-gpio"))
......@@ -764,8 +817,15 @@ static int iproc_gpio_probe(struct platform_device *pdev)
dev_err(dev, "unable to map I/O memory\n");
return PTR_ERR(chip->io_ctrl);
}
if (of_device_is_compatible(dev->of_node,
"brcm,cygnus-ccm-gpio"))
io_ctrl_type = IOCTRL_TYPE_CDRU;
else
io_ctrl_type = IOCTRL_TYPE_AON;
}
chip->io_ctrl_type = io_ctrl_type;
if (of_property_read_u32(dev->of_node, "ngpios", &ngpios)) {
dev_err(&pdev->dev, "missing ngpios DT property\n");
return -ENODEV;
......@@ -784,12 +844,42 @@ static int iproc_gpio_probe(struct platform_device *pdev)
gc->free = iproc_gpio_free;
gc->direction_input = iproc_gpio_direction_input;
gc->direction_output = iproc_gpio_direction_output;
gc->get_direction = iproc_gpio_get_direction;
gc->set = iproc_gpio_set;
gc->get = iproc_gpio_get;
chip->pinmux_is_supported = of_property_read_bool(dev->of_node,
"gpio-ranges");
/* optional GPIO interrupt support */
irq = platform_get_irq(pdev, 0);
if (irq) {
struct irq_chip *irqc;
struct gpio_irq_chip *girq;
irqc = &chip->irqchip;
irqc->name = "bcm-iproc-gpio";
irqc->irq_ack = iproc_gpio_irq_ack;
irqc->irq_mask = iproc_gpio_irq_mask;
irqc->irq_unmask = iproc_gpio_irq_unmask;
irqc->irq_set_type = iproc_gpio_irq_set_type;
irqc->irq_enable = iproc_gpio_irq_unmask;
irqc->irq_disable = iproc_gpio_irq_mask;
girq = &gc->irq;
girq->chip = irqc;
girq->parent_handler = iproc_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] = irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_simple_irq;
}
ret = gpiochip_add_data(gc, chip);
if (ret < 0) {
dev_err(dev, "unable to add GPIO chip\n");
......@@ -814,20 +904,6 @@ static int iproc_gpio_probe(struct platform_device *pdev)
}
}
/* optional GPIO interrupt support */
irq = platform_get_irq(pdev, 0);
if (irq) {
ret = gpiochip_irqchip_add(gc, &iproc_gpio_irq_chip, 0,
handle_simple_irq, IRQ_TYPE_NONE);
if (ret) {
dev_err(dev, "no GPIO irqchip\n");
goto err_rm_gpiochip;
}
gpiochip_set_chained_irqchip(gc, &iproc_gpio_irq_chip, irq,
iproc_gpio_irq_handler);
}
return 0;
err_rm_gpiochip:
......
......@@ -15,6 +15,9 @@ config PINCTRL_MADERA
select PINMUX
select GENERIC_PINCONF
config PINCTRL_CS47L15
bool
config PINCTRL_CS47L35
bool
......@@ -23,3 +26,6 @@ config PINCTRL_CS47L85
config PINCTRL_CS47L90
bool
config PINCTRL_CS47L92
bool
......@@ -3,6 +3,9 @@
obj-$(CONFIG_PINCTRL_LOCHNAGAR) += pinctrl-lochnagar.o
pinctrl-madera-objs := pinctrl-madera-core.o
ifeq ($(CONFIG_PINCTRL_CS47L15),y)
pinctrl-madera-objs += pinctrl-cs47l15.o
endif
ifeq ($(CONFIG_PINCTRL_CS47L35),y)
pinctrl-madera-objs += pinctrl-cs47l35.o
endif
......@@ -12,5 +15,8 @@ endif
ifeq ($(CONFIG_PINCTRL_CS47L90),y)
pinctrl-madera-objs += pinctrl-cs47l90.o
endif
ifeq ($(CONFIG_PINCTRL_CS47L92),y)
pinctrl-madera-objs += pinctrl-cs47l92.o
endif
obj-$(CONFIG_PINCTRL_MADERA) += pinctrl-madera.o
// SPDX-License-Identifier: GPL-2.0-only
/*
* Pinctrl for Cirrus Logic CS47L15
*
* Copyright (C) 2018-2019 Cirrus Logic, Inc. and
* Cirrus Logic International Semiconductor Ltd.
*/
#include <linux/err.h>
#include <linux/mfd/madera/core.h>
#include "pinctrl-madera.h"
/*
* The alt func groups are the most commonly used functions we place these at
* the lower function indexes for convenience, and the less commonly used gpio
* functions at higher indexes.
*
* To stay consistent with the datasheet the function names are the same as
* the group names for that function's pins
*
* Note - all 1 less than in datasheet because these are zero-indexed
*/
static const unsigned int cs47l15_aif1_pins[] = { 0, 1, 2, 3 };
static const unsigned int cs47l15_aif2_pins[] = { 4, 5, 6, 7 };
static const unsigned int cs47l15_aif3_pins[] = { 8, 9, 10, 11 };
static const unsigned int cs47l15_spk1_pins[] = { 12, 13, 14 };
static const struct madera_pin_groups cs47l15_pin_groups[] = {
{ "aif1", cs47l15_aif1_pins, ARRAY_SIZE(cs47l15_aif1_pins) },
{ "aif2", cs47l15_aif2_pins, ARRAY_SIZE(cs47l15_aif2_pins) },
{ "aif3", cs47l15_aif3_pins, ARRAY_SIZE(cs47l15_aif3_pins) },
{ "pdmspk1", cs47l15_spk1_pins, ARRAY_SIZE(cs47l15_spk1_pins) },
};
const struct madera_pin_chip cs47l15_pin_chip = {
.n_pins = CS47L15_NUM_GPIOS,
.pin_groups = cs47l15_pin_groups,
.n_pin_groups = ARRAY_SIZE(cs47l15_pin_groups),
};
// SPDX-License-Identifier: GPL-2.0-only
/*
* Pinctrl for Cirrus Logic CS47L92
*
* Copyright (C) 2018-2019 Cirrus Logic, Inc. and
* Cirrus Logic International Semiconductor Ltd.
*/
#include <linux/err.h>
#include <linux/mfd/madera/core.h>
#include "pinctrl-madera.h"
/*
* The alt func groups are the most commonly used functions we place these at
* the lower function indexes for convenience, and the less commonly used gpio
* functions at higher indexes.
*
* To stay consistent with the datasheet the function names are the same as
* the group names for that function's pins
*
* Note - all 1 less than in datasheet because these are zero-indexed
*/
static const unsigned int cs47l92_spk1_pins[] = { 2, 3 };
static const unsigned int cs47l92_aif1_pins[] = { 4, 5, 6, 7 };
static const unsigned int cs47l92_aif2_pins[] = { 8, 9, 10, 11 };
static const unsigned int cs47l92_aif3_pins[] = { 12, 13, 14, 15 };
static const struct madera_pin_groups cs47l92_pin_groups[] = {
{ "aif1", cs47l92_aif1_pins, ARRAY_SIZE(cs47l92_aif1_pins) },
{ "aif2", cs47l92_aif2_pins, ARRAY_SIZE(cs47l92_aif2_pins) },
{ "aif3", cs47l92_aif3_pins, ARRAY_SIZE(cs47l92_aif3_pins) },
{ "pdmspk1", cs47l92_spk1_pins, ARRAY_SIZE(cs47l92_spk1_pins) },
};
const struct madera_pin_chip cs47l92_pin_chip = {
.n_pins = CS47L92_NUM_GPIOS,
.pin_groups = cs47l92_pin_groups,
.n_pin_groups = ARRAY_SIZE(cs47l92_pin_groups),
};
......@@ -396,6 +396,16 @@ static const struct {
.group_names = madera_pin_single_group_names,
.func = 0x157
},
{
.name = "aux-pdm-clk",
.group_names = madera_pin_single_group_names,
.func = 0x280
},
{
.name = "aux-pdm-dat",
.group_names = madera_pin_single_group_names,
.func = 0x281
},
};
static u16 madera_pin_make_drv_str(struct madera_pin_private *priv,
......@@ -986,7 +996,7 @@ static struct pinctrl_desc madera_pin_desc = {
static int madera_pin_probe(struct platform_device *pdev)
{
struct madera *madera = dev_get_drvdata(pdev->dev.parent);
const struct madera_pdata *pdata = dev_get_platdata(madera->dev);
const struct madera_pdata *pdata = &madera->pdata;
struct madera_pin_private *priv;
int ret;
......@@ -1004,6 +1014,10 @@ static int madera_pin_probe(struct platform_device *pdev)
pdev->dev.of_node = madera->dev->of_node;
switch (madera->type) {
case CS47L15:
if (IS_ENABLED(CONFIG_PINCTRL_CS47L15))
priv->chip = &cs47l15_pin_chip;
break;
case CS47L35:
if (IS_ENABLED(CONFIG_PINCTRL_CS47L35))
priv->chip = &cs47l35_pin_chip;
......@@ -1018,6 +1032,12 @@ static int madera_pin_probe(struct platform_device *pdev)
if (IS_ENABLED(CONFIG_PINCTRL_CS47L90))
priv->chip = &cs47l90_pin_chip;
break;
case CS42L92:
case CS47L92:
case CS47L93:
if (IS_ENABLED(CONFIG_PINCTRL_CS47L92))
priv->chip = &cs47l92_pin_chip;
break;
default:
break;
}
......@@ -1037,7 +1057,7 @@ static int madera_pin_probe(struct platform_device *pdev)
}
/* if the configuration is provided through pdata, apply it */
if (pdata && pdata->gpio_configs) {
if (pdata->gpio_configs) {
ret = pinctrl_register_mappings(pdata->gpio_configs,
pdata->n_gpio_configs);
if (ret) {
......
......@@ -30,8 +30,10 @@ struct madera_pin_private {
struct pinctrl_dev *pctl;
};
extern const struct madera_pin_chip cs47l15_pin_chip;
extern const struct madera_pin_chip cs47l35_pin_chip;
extern const struct madera_pin_chip cs47l85_pin_chip;
extern const struct madera_pin_chip cs47l90_pin_chip;
extern const struct madera_pin_chip cs47l92_pin_chip;
#endif
......@@ -736,6 +736,34 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
return -EINVAL;
}
bool pinctrl_gpio_can_use_line(unsigned gpio)
{
struct pinctrl_dev *pctldev;
struct pinctrl_gpio_range *range;
bool result;
int pin;
/*
* Try to obtain GPIO range, if it fails
* we're probably dealing with GPIO driver
* without a backing pin controller - bail out.
*/
if (pinctrl_get_device_gpio_range(gpio, &pctldev, &range))
return true;
mutex_lock(&pctldev->mutex);
/* Convert to the pin controllers number space */
pin = gpio_to_pin(range, gpio);
result = pinmux_can_be_used_for_gpio(pctldev, pin);
mutex_unlock(&pctldev->mutex);
return result;
}
EXPORT_SYMBOL_GPL(pinctrl_gpio_can_use_line);
/**
* pinctrl_gpio_request() - request a single pin to be used as GPIO
* @gpio: the GPIO pin number from the GPIO subsystem number space
......
......@@ -228,10 +228,8 @@ int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
* than dynamically allocate it and have to free it later,
* just point part way into the property name for the string.
*/
if (ret < 0) {
/* strlen("pinctrl-") == 8 */
statename = prop->name + 8;
}
if (ret < 0)
statename = prop->name + strlen("pinctrl-");
/* For every referenced pin configuration node in it */
for (config = 0; config < size; config++) {
......
......@@ -672,8 +672,10 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
grp = devm_kzalloc(ipctl->dev, sizeof(struct group_desc),
GFP_KERNEL);
if (!grp)
if (!grp) {
of_node_put(child);
return -ENOMEM;
}
mutex_lock(&ipctl->mutex);
radix_tree_insert(&pctl->pin_group_tree,
......@@ -697,12 +699,17 @@ static bool imx_pinctrl_dt_is_flat_functions(struct device_node *np)
struct device_node *pinctrl_np;
for_each_child_of_node(np, function_np) {
if (of_property_read_bool(function_np, "fsl,pins"))
if (of_property_read_bool(function_np, "fsl,pins")) {
of_node_put(function_np);
return true;
}
for_each_child_of_node(function_np, pinctrl_np) {
if (of_property_read_bool(pinctrl_np, "fsl,pins"))
if (of_property_read_bool(pinctrl_np, "fsl,pins")) {
of_node_put(pinctrl_np);
of_node_put(function_np);
return false;
}
}
}
......
......@@ -488,8 +488,10 @@ static int mxs_pinctrl_probe_dt(struct platform_device *pdev,
if (of_property_read_u32(child, "reg", &val)) {
ret = mxs_pinctrl_parse_group(pdev, child,
idxg++, NULL);
if (ret)
if (ret) {
of_node_put(child);
return ret;
}
continue;
}
......@@ -499,15 +501,19 @@ static int mxs_pinctrl_probe_dt(struct platform_device *pdev,
f->ngroups,
sizeof(*f->groups),
GFP_KERNEL);
if (!f->groups)
if (!f->groups) {
of_node_put(child);
return -ENOMEM;
}
fn = child->name;
i = 0;
}
ret = mxs_pinctrl_parse_group(pdev, child, idxg++,
&f->groups[i++]);
if (ret)
if (ret) {
of_node_put(child);
return ret;
}
}
return 0;
......
......@@ -98,13 +98,6 @@ struct byt_gpio_pin_context {
u32 val;
};
struct byt_community {
unsigned int pin_base;
size_t npins;
const unsigned int *pad_map;
void __iomem *reg_base;
};
#define COMMUNITY(p, n, map) \
{ \
.pin_base = (p), \
......@@ -112,26 +105,14 @@ struct byt_community {
.pad_map = (map),\
}
struct byt_pinctrl_soc_data {
const char *uid;
const struct pinctrl_pin_desc *pins;
size_t npins;
const struct intel_pingroup *groups;
size_t ngroups;
const struct intel_function *functions;
size_t nfunctions;
const struct byt_community *communities;
size_t ncommunities;
};
struct byt_gpio {
struct gpio_chip chip;
struct platform_device *pdev;
struct pinctrl_dev *pctl_dev;
struct pinctrl_desc pctl_desc;
raw_spinlock_t lock;
const struct byt_pinctrl_soc_data *soc_data;
struct byt_community *communities_copy;
const struct intel_pinctrl_soc_data *soc_data;
struct intel_community *communities_copy;
struct byt_gpio_pin_context *saved_context;
};
......@@ -383,11 +364,11 @@ static const struct intel_function byt_score_functions[] = {
FUNCTION("gpio", byt_score_gpio_groups),
};
static const struct byt_community byt_score_communities[] = {
static const struct intel_community byt_score_communities[] = {
COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map),
};
static const struct byt_pinctrl_soc_data byt_score_soc_data = {
static const struct intel_pinctrl_soc_data byt_score_soc_data = {
.uid = BYT_SCORE_ACPI_UID,
.pins = byt_score_pins,
.npins = ARRAY_SIZE(byt_score_pins),
......@@ -496,11 +477,11 @@ static const struct intel_function byt_sus_functions[] = {
FUNCTION("gpio", byt_sus_gpio_groups),
};
static const struct byt_community byt_sus_communities[] = {
static const struct intel_community byt_sus_communities[] = {
COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map),
};
static const struct byt_pinctrl_soc_data byt_sus_soc_data = {
static const struct intel_pinctrl_soc_data byt_sus_soc_data = {
.uid = BYT_SUS_ACPI_UID,
.pins = byt_sus_pins,
.npins = ARRAY_SIZE(byt_sus_pins),
......@@ -549,11 +530,11 @@ static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = {
3, 6, 10, 13, 2, 5, 9, 7,
};
static const struct byt_community byt_ncore_communities[] = {
static const struct intel_community byt_ncore_communities[] = {
COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map),
};
static const struct byt_pinctrl_soc_data byt_ncore_soc_data = {
static const struct intel_pinctrl_soc_data byt_ncore_soc_data = {
.uid = BYT_NCORE_ACPI_UID,
.pins = byt_ncore_pins,
.npins = ARRAY_SIZE(byt_ncore_pins),
......@@ -561,17 +542,17 @@ static const struct byt_pinctrl_soc_data byt_ncore_soc_data = {
.ncommunities = ARRAY_SIZE(byt_ncore_communities),
};
static const struct byt_pinctrl_soc_data *byt_soc_data[] = {
static const struct intel_pinctrl_soc_data *byt_soc_data[] = {
&byt_score_soc_data,
&byt_sus_soc_data,
&byt_ncore_soc_data,
NULL
};
static struct byt_community *byt_get_community(struct byt_gpio *vg,
unsigned int pin)
static struct intel_community *byt_get_community(struct byt_gpio *vg,
unsigned int pin)
{
struct byt_community *comm;
struct intel_community *comm;
int i;
for (i = 0; i < vg->soc_data->ncommunities; i++) {
......@@ -586,7 +567,7 @@ static struct byt_community *byt_get_community(struct byt_gpio *vg,
static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset,
int reg)
{
struct byt_community *comm = byt_get_community(vg, offset);
struct intel_community *comm = byt_get_community(vg, offset);
u32 reg_offset;
if (!comm)
......@@ -605,7 +586,7 @@ static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset,
break;
}
return comm->reg_base + reg_offset + reg;
return comm->pad_regs + reg_offset + reg;
}
static int byt_get_groups_count(struct pinctrl_dev *pctldev)
......@@ -1211,7 +1192,7 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
u32 conf0, val;
for (i = 0; i < vg->soc_data->npins; i++) {
const struct byt_community *comm;
const struct intel_community *comm;
const char *pull_str = NULL;
const char *pull = NULL;
void __iomem *reg;
......@@ -1580,7 +1561,7 @@ static int byt_gpio_probe(struct byt_gpio *vg)
}
static int byt_set_soc_data(struct byt_gpio *vg,
const struct byt_pinctrl_soc_data *soc_data)
const struct intel_pinctrl_soc_data *soc_data)
{
int i;
......@@ -1593,15 +1574,13 @@ static int byt_set_soc_data(struct byt_gpio *vg,
return -ENOMEM;
for (i = 0; i < soc_data->ncommunities; i++) {
struct byt_community *comm = vg->communities_copy + i;
struct resource *mem_rc;
struct intel_community *comm = vg->communities_copy + i;
*comm = vg->soc_data->communities[i];
mem_rc = platform_get_resource(vg->pdev, IORESOURCE_MEM, 0);
comm->reg_base = devm_ioremap_resource(&vg->pdev->dev, mem_rc);
if (IS_ERR(comm->reg_base))
return PTR_ERR(comm->reg_base);
comm->pad_regs = devm_platform_ioremap_resource(vg->pdev, 0);
if (IS_ERR(comm->pad_regs))
return PTR_ERR(comm->pad_regs);
}
return 0;
......@@ -1615,8 +1594,8 @@ static const struct acpi_device_id byt_gpio_acpi_match[] = {
static int byt_pinctrl_probe(struct platform_device *pdev)
{
const struct byt_pinctrl_soc_data *soc_data = NULL;
const struct byt_pinctrl_soc_data **soc_table;
const struct intel_pinctrl_soc_data *soc_data = NULL;
const struct intel_pinctrl_soc_data **soc_table;
struct acpi_device *acpi_dev;
struct byt_gpio *vg;
int i, ret;
......@@ -1625,7 +1604,7 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
if (!acpi_dev)
return -ENODEV;
soc_table = (const struct byt_pinctrl_soc_data **)device_get_match_data(&pdev->dev);
soc_table = (const struct intel_pinctrl_soc_data **)device_get_match_data(&pdev->dev);
for (i = 0; soc_table[i]; i++) {
if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) {
......
......@@ -15,8 +15,9 @@
#include "pinctrl-intel.h"
#define BXT_PAD_OWN 0x020
#define BXT_HOSTSW_OWN 0x080
#define BXT_PADCFGLOCK 0x060
#define BXT_HOSTSW_OWN 0x080
#define BXT_GPI_IS 0x100
#define BXT_GPI_IE 0x110
#define BXT_COMMUNITY(s, e) \
......@@ -24,6 +25,7 @@
.padown_offset = BXT_PAD_OWN, \
.padcfglock_offset = BXT_PADCFGLOCK, \
.hostown_offset = BXT_HOSTSW_OWN, \
.is_offset = BXT_GPI_IS, \
.ie_offset = BXT_GPI_IE, \
.gpp_size = 32, \
.pin_base = (s), \
......
......@@ -19,6 +19,7 @@
#define CNL_PADCFGLOCK 0x080
#define CNL_LP_HOSTSW_OWN 0x0b0
#define CNL_H_HOSTSW_OWN 0x0c0
#define CNL_GPI_IS 0x100
#define CNL_GPI_IE 0x120
#define CNL_GPP(r, s, e, g) \
......@@ -37,6 +38,7 @@
.padown_offset = CNL_PAD_OWN, \
.padcfglock_offset = CNL_PADCFGLOCK, \
.hostown_offset = (o), \
.is_offset = CNL_GPI_IS, \
.ie_offset = CNL_GPI_IE, \
.pin_base = (s), \
.npins = ((e) - (s) + 1), \
......
......@@ -1677,7 +1677,6 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
{
struct chv_pinctrl *pctrl;
struct acpi_device *adev;
struct resource *res;
acpi_status status;
int ret, irq, i;
......@@ -1707,16 +1706,13 @@ static int chv_pinctrl_probe(struct platform_device *pdev)
return -ENOMEM;
#endif
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pctrl->regs = devm_ioremap_resource(&pdev->dev, res);
pctrl->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pctrl->regs))
return PTR_ERR(pctrl->regs);
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "failed to get interrupt number\n");
if (irq < 0)
return irq;
}
pctrl->pctldesc = chv_pinctrl_desc;
pctrl->pctldesc.name = dev_name(&pdev->dev);
......
......@@ -15,8 +15,9 @@
#include "pinctrl-intel.h"
#define DNV_PAD_OWN 0x020
#define DNV_HOSTSW_OWN 0x0C0
#define DNV_PADCFGLOCK 0x090
#define DNV_HOSTSW_OWN 0x0C0
#define DNV_GPI_IS 0x100
#define DNV_GPI_IE 0x120
#define DNV_GPP(n, s, e) \
......@@ -32,6 +33,7 @@
.padown_offset = DNV_PAD_OWN, \
.padcfglock_offset = DNV_PADCFGLOCK, \
.hostown_offset = DNV_HOSTSW_OWN, \
.is_offset = DNV_GPI_IS, \
.ie_offset = DNV_GPI_IE, \
.pin_base = (s), \
.npins = ((e) - (s) + 1), \
......@@ -39,6 +41,7 @@
.ngpps = ARRAY_SIZE(g), \
}
/* Denverton */
static const struct pinctrl_pin_desc dnv_pins[] = {
/* North ALL */
PINCTRL_PIN(0, "GBE0_SDP0"),
......@@ -59,7 +62,7 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
PINCTRL_PIN(15, "NCSI_CLK_IN"),
PINCTRL_PIN(16, "NCSI_RXD1"),
PINCTRL_PIN(17, "NCSI_CRS_DV"),
PINCTRL_PIN(18, "NCSI_ARB_IN"),
PINCTRL_PIN(18, "IDSLDO_VID_TICKLE"),
PINCTRL_PIN(19, "NCSI_TX_EN"),
PINCTRL_PIN(20, "NCSI_TXD0"),
PINCTRL_PIN(21, "NCSI_TXD1"),
......@@ -68,14 +71,14 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
PINCTRL_PIN(24, "GBE0_LED1"),
PINCTRL_PIN(25, "GBE1_LED0"),
PINCTRL_PIN(26, "GBE1_LED1"),
PINCTRL_PIN(27, "GPIO_0"),
PINCTRL_PIN(27, "SPARE_0"),
PINCTRL_PIN(28, "PCIE_CLKREQ0_N"),
PINCTRL_PIN(29, "PCIE_CLKREQ1_N"),
PINCTRL_PIN(30, "PCIE_CLKREQ2_N"),
PINCTRL_PIN(31, "PCIE_CLKREQ3_N"),
PINCTRL_PIN(32, "PCIE_CLKREQ4_N"),
PINCTRL_PIN(33, "GPIO_1"),
PINCTRL_PIN(34, "GPIO_2"),
PINCTRL_PIN(33, "GBE_MDC"),
PINCTRL_PIN(34, "GBE_MDIO"),
PINCTRL_PIN(35, "SVID_ALERT_N"),
PINCTRL_PIN(36, "SVID_DATA"),
PINCTRL_PIN(37, "SVID_CLK"),
......@@ -102,15 +105,15 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
PINCTRL_PIN(57, "DFX_PORT14"),
PINCTRL_PIN(58, "DFX_PORT15"),
/* South GPP0 */
PINCTRL_PIN(59, "GPIO_12"),
PINCTRL_PIN(60, "SMB5_GBE_ALRT_N"),
PINCTRL_PIN(59, "SPI_TPM_CS_N"),
PINCTRL_PIN(60, "UART2_CTS"),
PINCTRL_PIN(61, "PCIE_CLKREQ5_N"),
PINCTRL_PIN(62, "PCIE_CLKREQ6_N"),
PINCTRL_PIN(63, "PCIE_CLKREQ7_N"),
PINCTRL_PIN(64, "UART0_RXD"),
PINCTRL_PIN(65, "UART0_TXD"),
PINCTRL_PIN(66, "SMB5_GBE_CLK"),
PINCTRL_PIN(67, "SMB5_GBE_DATA"),
PINCTRL_PIN(66, "CPU_RESET_N"),
PINCTRL_PIN(67, "NMI"),
PINCTRL_PIN(68, "ERROR2_N"),
PINCTRL_PIN(69, "ERROR1_N"),
PINCTRL_PIN(70, "ERROR0_N"),
......@@ -129,20 +132,20 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
PINCTRL_PIN(83, "USB_OC0_N"),
PINCTRL_PIN(84, "FLEX_CLK_SE0"),
PINCTRL_PIN(85, "FLEX_CLK_SE1"),
PINCTRL_PIN(86, "GPIO_4"),
PINCTRL_PIN(87, "GPIO_5"),
PINCTRL_PIN(88, "GPIO_6"),
PINCTRL_PIN(89, "GPIO_7"),
PINCTRL_PIN(86, "SPARE_4"),
PINCTRL_PIN(87, "SMB3_IE0_CLK"),
PINCTRL_PIN(88, "SMB3_IE0_DATA"),
PINCTRL_PIN(89, "SMB3_IE0_ALRT_N"),
PINCTRL_PIN(90, "SATA0_LED_N"),
PINCTRL_PIN(91, "SATA1_LED_N"),
PINCTRL_PIN(92, "SATA_PDETECT0"),
PINCTRL_PIN(93, "SATA_PDETECT1"),
PINCTRL_PIN(94, "SATA0_SDOUT"),
PINCTRL_PIN(95, "SATA1_SDOUT"),
PINCTRL_PIN(94, "UART1_RTS"),
PINCTRL_PIN(95, "UART1_CTS"),
PINCTRL_PIN(96, "UART1_RXD"),
PINCTRL_PIN(97, "UART1_TXD"),
PINCTRL_PIN(98, "GPIO_8"),
PINCTRL_PIN(99, "GPIO_9"),
PINCTRL_PIN(98, "SPARE_8"),
PINCTRL_PIN(99, "SPARE_9"),
PINCTRL_PIN(100, "TCK"),
PINCTRL_PIN(101, "TRST_N"),
PINCTRL_PIN(102, "TMS"),
......@@ -150,11 +153,11 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
PINCTRL_PIN(104, "TDO"),
PINCTRL_PIN(105, "CX_PRDY_N"),
PINCTRL_PIN(106, "CX_PREQ_N"),
PINCTRL_PIN(107, "CTBTRIGINOUT"),
PINCTRL_PIN(108, "CTBTRIGOUT"),
PINCTRL_PIN(109, "DFX_SPARE2"),
PINCTRL_PIN(110, "DFX_SPARE3"),
PINCTRL_PIN(111, "DFX_SPARE4"),
PINCTRL_PIN(107, "TAP1_TCK"),
PINCTRL_PIN(108, "TAP1_TRST_N"),
PINCTRL_PIN(109, "TAP1_TMS"),
PINCTRL_PIN(110, "TAP1_TDI"),
PINCTRL_PIN(111, "TAP1_TDO"),
/* South GPP1 */
PINCTRL_PIN(112, "SUSPWRDNACK"),
PINCTRL_PIN(113, "PMU_SUSCLK"),
......@@ -183,8 +186,8 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
PINCTRL_PIN(136, "ESPI_CLK"),
PINCTRL_PIN(137, "ESPI_RST_N"),
PINCTRL_PIN(138, "ESPI_ALRT0_N"),
PINCTRL_PIN(139, "GPIO_10"),
PINCTRL_PIN(140, "GPIO_11"),
PINCTRL_PIN(139, "ESPI_CS1_N"),
PINCTRL_PIN(140, "ESPI_ALRT1_N"),
PINCTRL_PIN(141, "ESPI_CLK_LOOPBK"),
PINCTRL_PIN(142, "EMMC_CMD"),
PINCTRL_PIN(143, "EMMC_STROBE"),
......@@ -197,7 +200,7 @@ static const struct pinctrl_pin_desc dnv_pins[] = {
PINCTRL_PIN(150, "EMMC_D5"),
PINCTRL_PIN(151, "EMMC_D6"),
PINCTRL_PIN(152, "EMMC_D7"),
PINCTRL_PIN(153, "GPIO_3"),
PINCTRL_PIN(153, "SPARE_3"),
};
static const unsigned int dnv_uart0_pins[] = { 60, 61, 64, 65 };
......
......@@ -17,6 +17,7 @@
#define GLK_PAD_OWN 0x020
#define GLK_PADCFGLOCK 0x080
#define GLK_HOSTSW_OWN 0x0b0
#define GLK_GPI_IS 0x100
#define GLK_GPI_IE 0x110
#define GLK_COMMUNITY(s, e) \
......@@ -24,6 +25,7 @@
.padown_offset = GLK_PAD_OWN, \
.padcfglock_offset = GLK_PADCFGLOCK, \
.hostown_offset = GLK_HOSTSW_OWN, \
.is_offset = GLK_GPI_IS, \
.ie_offset = GLK_GPI_IE, \
.gpp_size = 32, \
.pin_base = (s), \
......
......@@ -18,6 +18,7 @@
#define ICL_PAD_OWN 0x020
#define ICL_PADCFGLOCK 0x080
#define ICL_HOSTSW_OWN 0x0b0
#define ICL_GPI_IS 0x100
#define ICL_GPI_IE 0x110
#define ICL_GPP(r, s, e, g) \
......@@ -36,6 +37,7 @@
.padown_offset = ICL_PAD_OWN, \
.padcfglock_offset = ICL_PADCFGLOCK, \
.hostown_offset = ICL_HOSTSW_OWN, \
.is_offset = ICL_GPI_IS, \
.ie_offset = ICL_GPI_IE, \
.pin_base = (s), \
.npins = ((e) - (s) + 1), \
......
......@@ -8,12 +8,13 @@
*/
#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/gpio/driver.h>
#include <linux/log2.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/time.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
......@@ -29,7 +30,6 @@
#define REVID_MASK GENMASK(31, 16)
#define PADBAR 0x00c
#define GPI_IS 0x100
#define PADOWN_BITS 4
#define PADOWN_SHIFT(p) ((p) % 8 * PADOWN_BITS)
......@@ -71,7 +71,7 @@
#define PADCFG2_DEBOUNCE_SHIFT 1
#define PADCFG2_DEBOUNCE_MASK GENMASK(4, 1)
#define DEBOUNCE_PERIOD 31250 /* ns */
#define DEBOUNCE_PERIOD_NSEC 31250
struct intel_pad_context {
u32 padcfg0;
......@@ -165,7 +165,7 @@ static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl,
padno = pin_to_padno(community, pin);
nregs = (community->features & PINCTRL_FEATURE_DEBOUNCE) ? 4 : 2;
if (reg == PADCFG2 && !(community->features & PINCTRL_FEATURE_DEBOUNCE))
if (reg >= nregs * 4)
return NULL;
return community->pad_regs + reg + padno * nregs * 4;
......@@ -220,47 +220,71 @@ static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned int pin)
return !(readl(hostown) & BIT(gpp_offset));
}
static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin)
/**
* enum - Locking variants of the pad configuration
*
* @PAD_UNLOCKED: pad is fully controlled by the configuration registers
* @PAD_LOCKED: pad configuration registers, except TX state, are locked
* @PAD_LOCKED_TX: pad configuration TX state is locked
* @PAD_LOCKED_FULL: pad configuration registers are locked completely
*
* Locking is considered as read-only mode for corresponding registers and
* their respective fields. That said, TX state bit is locked separately from
* the main locking scheme.
*/
enum {
PAD_UNLOCKED = 0,
PAD_LOCKED = 1,
PAD_LOCKED_TX = 2,
PAD_LOCKED_FULL = PAD_LOCKED | PAD_LOCKED_TX,
};
static int intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin)
{
struct intel_community *community;
const struct intel_padgroup *padgrp;
unsigned int offset, gpp_offset;
u32 value;
int ret = PAD_UNLOCKED;
community = intel_get_community(pctrl, pin);
if (!community)
return true;
return PAD_LOCKED_FULL;
if (!community->padcfglock_offset)
return false;
return PAD_UNLOCKED;
padgrp = intel_community_get_padgroup(community, pin);
if (!padgrp)
return true;
return PAD_LOCKED_FULL;
gpp_offset = padgroup_offset(padgrp, pin);
/*
* If PADCFGLOCK and PADCFGLOCKTX bits are both clear for this pad,
* the pad is considered unlocked. Any other case means that it is
* either fully or partially locked and we don't touch it.
* either fully or partially locked.
*/
offset = community->padcfglock_offset + padgrp->reg_num * 8;
offset = community->padcfglock_offset + 0 + padgrp->reg_num * 8;
value = readl(community->regs + offset);
if (value & BIT(gpp_offset))
return true;
ret |= PAD_LOCKED;
offset = community->padcfglock_offset + 4 + padgrp->reg_num * 8;
value = readl(community->regs + offset);
if (value & BIT(gpp_offset))
return true;
ret |= PAD_LOCKED_TX;
return false;
return ret;
}
static bool intel_pad_is_unlocked(struct intel_pinctrl *pctrl, unsigned int pin)
{
return (intel_pad_locked(pctrl, pin) & PAD_LOCKED) == PAD_UNLOCKED;
}
static bool intel_pad_usable(struct intel_pinctrl *pctrl, unsigned int pin)
{
return intel_pad_owned_by_host(pctrl, pin) &&
!intel_pad_locked(pctrl, pin);
return intel_pad_owned_by_host(pctrl, pin) && intel_pad_is_unlocked(pctrl, pin);
}
static int intel_get_groups_count(struct pinctrl_dev *pctldev)
......@@ -294,7 +318,8 @@ static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
void __iomem *padcfg;
u32 cfg0, cfg1, mode;
bool locked, acpi;
int locked;
bool acpi;
if (!intel_pad_owned_by_host(pctrl, pin)) {
seq_puts(s, "not available");
......@@ -322,11 +347,16 @@ static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
if (locked || acpi) {
seq_puts(s, " [");
if (locked) {
if (locked)
seq_puts(s, "LOCKED");
if (acpi)
seq_puts(s, ", ");
}
if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_TX)
seq_puts(s, " tx");
else if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_FULL)
seq_puts(s, " full");
if (locked && acpi)
seq_puts(s, ", ");
if (acpi)
seq_puts(s, "ACPI");
seq_puts(s, "]");
......@@ -448,11 +478,16 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
raw_spin_lock_irqsave(&pctrl->lock, flags);
if (!intel_pad_usable(pctrl, pin)) {
if (!intel_pad_owned_by_host(pctrl, pin)) {
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
return -EBUSY;
}
if (!intel_pad_is_unlocked(pctrl, pin)) {
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
return 0;
}
padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
intel_gpio_set_gpio_mode(padcfg0);
/* Disable TX buffer and enable RX (this will be input) */
......@@ -566,7 +601,7 @@ static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
return -EINVAL;
v = (v & PADCFG2_DEBOUNCE_MASK) >> PADCFG2_DEBOUNCE_SHIFT;
arg = BIT(v) * DEBOUNCE_PERIOD / 1000;
arg = BIT(v) * DEBOUNCE_PERIOD_NSEC / NSEC_PER_USEC;
break;
}
......@@ -683,7 +718,7 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl,
if (debounce) {
unsigned long v;
v = order_base_2(debounce * 1000 / DEBOUNCE_PERIOD);
v = order_base_2(debounce * NSEC_PER_USEC / DEBOUNCE_PERIOD_NSEC);
if (v < 3 || v > 15) {
ret = -EINVAL;
goto exit_unlock;
......@@ -796,6 +831,29 @@ static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset,
return -EINVAL;
}
/**
* intel_pin_to_gpio() - Translate from pin number to GPIO offset
* @pctrl: Pinctrl structure
* @pin: pin number
*
* Translate the pin number of pinctrl to GPIO offset
*/
static __maybe_unused int intel_pin_to_gpio(struct intel_pinctrl *pctrl, int pin)
{
const struct intel_community *community;
const struct intel_padgroup *padgrp;
community = intel_get_community(pctrl, pin);
if (!community)
return -EINVAL;
padgrp = intel_community_get_padgroup(community, pin);
if (!padgrp)
return -EINVAL;
return pin - padgrp->base + padgrp->gpio_base;
}
static int intel_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
......@@ -1313,15 +1371,12 @@ static int intel_pinctrl_probe(struct platform_device *pdev,
for (i = 0; i < pctrl->ncommunities; i++) {
struct intel_community *community = &pctrl->communities[i];
struct resource *res;
void __iomem *regs;
u32 padbar;
*community = pctrl->soc->communities[i];
res = platform_get_resource(pdev, IORESOURCE_MEM,
community->barno);
regs = devm_ioremap_resource(&pdev->dev, res);
regs = devm_platform_ioremap_resource(pdev, community->barno);
if (IS_ERR(regs))
return PTR_ERR(regs);
......@@ -1345,19 +1400,14 @@ static int intel_pinctrl_probe(struct platform_device *pdev,
community->regs = regs;
community->pad_regs = regs + padbar;
if (!community->is_offset)
community->is_offset = GPI_IS;
ret = intel_pinctrl_add_padgroups(pctrl, community);
if (ret)
return ret;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "failed to get interrupt number\n");
if (irq < 0)
return irq;
}
ret = intel_pinctrl_pm_init(pctrl);
if (ret)
......@@ -1421,8 +1471,6 @@ int intel_pinctrl_probe_by_uid(struct platform_device *pdev)
table = (const struct intel_pinctrl_soc_data **)id->driver_data;
data = table[pdev->id];
}
if (!data)
return -ENODEV;
return intel_pinctrl_probe(pdev, data);
}
......@@ -1443,7 +1491,7 @@ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int
* them alone.
*/
if (pd->mux_owner || pd->gpio_owner ||
gpiochip_line_is_irq(&pctrl->chip, pin))
gpiochip_line_is_irq(&pctrl->chip, intel_pin_to_gpio(pctrl, pin)))
return true;
return false;
......
......@@ -75,9 +75,9 @@ struct intel_padgroup {
* @hostown_offset: Register offset of HOSTSW_OWN from @regs. If %0 then it
* is assumed that the host owns the pin (rather than
* ACPI).
* @is_offset: Register offset of GPI_IS from @regs. If %0 then uses the
* default (%0x100).
* @is_offset: Register offset of GPI_IS from @regs.
* @ie_offset: Register offset of GPI_IE from @regs.
* @features: Additional features supported by the hardware
* @pin_base: Starting pin of pins in this community
* @gpp_size: Maximum number of pads in each group, such as PADCFGLOCK,
* HOSTSW_OWN, GPI_IS, GPI_IE, etc. Used when @gpps is %NULL.
......@@ -85,9 +85,9 @@ struct intel_padgroup {
* minimum. Use %0 if the number of registers can be
* determined by the size of the group.
* @npins: Number of pins in this community
* @features: Additional features supported by the hardware
* @gpps: Pad groups if the controller has variable size pad groups
* @ngpps: Number of pad groups in this community
* @pad_map: Optional non-linear mapping of the pads
* @regs: Community specific common registers (reserved for core driver)
* @pad_regs: Community specific pad registers (reserved for core driver)
*
......@@ -104,13 +104,14 @@ struct intel_community {
unsigned int hostown_offset;
unsigned int is_offset;
unsigned int ie_offset;
unsigned int features;
unsigned int pin_base;
unsigned int gpp_size;
unsigned int gpp_num_padown_regs;
size_t npins;
unsigned int features;
const struct intel_padgroup *gpps;
size_t ngpps;
const unsigned int *pad_map;
/* Reserved for the core driver */
void __iomem *regs;
void __iomem *pad_regs;
......
......@@ -17,6 +17,7 @@
#define LBG_PAD_OWN 0x020
#define LBG_PADCFGLOCK 0x060
#define LBG_HOSTSW_OWN 0x080
#define LBG_GPI_IS 0x100
#define LBG_GPI_IE 0x110
#define LBG_COMMUNITY(b, s, e) \
......@@ -25,6 +26,7 @@
.padown_offset = LBG_PAD_OWN, \
.padcfglock_offset = LBG_PADCFGLOCK, \
.hostown_offset = LBG_HOSTSW_OWN, \
.is_offset = LBG_GPI_IS, \
.ie_offset = LBG_GPI_IE, \
.gpp_size = 24, \
.pin_base = (s), \
......
......@@ -885,7 +885,6 @@ static int mrfld_pinctrl_probe(struct platform_device *pdev)
{
struct mrfld_family *families;
struct mrfld_pinctrl *mp;
struct resource *mem;
void __iomem *regs;
size_t nfamilies;
unsigned int i;
......@@ -897,8 +896,7 @@ static int mrfld_pinctrl_probe(struct platform_device *pdev)
mp->dev = &pdev->dev;
raw_spin_lock_init(&mp->lock);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
regs = devm_ioremap_resource(&pdev->dev, mem);
regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(regs))
return PTR_ERR(regs);
......
......@@ -18,6 +18,7 @@
#define SPT_PAD_OWN 0x020
#define SPT_PADCFGLOCK 0x0a0
#define SPT_HOSTSW_OWN 0x0d0
#define SPT_GPI_IS 0x100
#define SPT_GPI_IE 0x120
#define SPT_COMMUNITY(b, s, e) \
......@@ -26,6 +27,7 @@
.padown_offset = SPT_PAD_OWN, \
.padcfglock_offset = SPT_PADCFGLOCK, \
.hostown_offset = SPT_HOSTSW_OWN, \
.is_offset = SPT_GPI_IS, \
.ie_offset = SPT_GPI_IE, \
.gpp_size = 24, \
.gpp_num_padown_regs = 4, \
......
......@@ -801,6 +801,9 @@ static const unsigned int remote_ao_input_pins[] = { GPIOAO_5 };
/* ir_out */
static const unsigned int remote_ao_out_pins[] = { GPIOAO_4 };
/* pwm_a_e */
static const unsigned int pwm_a_e_pins[] = { GPIOE_2 };
/* pwm_ao_a */
static const unsigned int pwm_ao_a_pins[] = { GPIOAO_11 };
static const unsigned int pwm_ao_a_hiz_pins[] = { GPIOAO_11 };
......@@ -888,6 +891,7 @@ static struct meson_pmx_group meson_g12a_aobus_groups[] = {
GROUP(i2c_ao_slave_sda, 3),
GROUP(remote_ao_input, 1),
GROUP(remote_ao_out, 1),
GROUP(pwm_a_e, 3),
GROUP(pwm_ao_a, 3),
GROUP(pwm_ao_a_hiz, 2),
GROUP(pwm_ao_b, 3),
......@@ -1192,6 +1196,10 @@ static const char * const remote_ao_out_groups[] = {
"remote_ao_out",
};
static const char * const pwm_a_e_groups[] = {
"pwm_a_e",
};
static const char * const pwm_ao_a_groups[] = {
"pwm_ao_a", "pwm_ao_a_hiz",
};
......@@ -1290,6 +1298,7 @@ static struct meson_pmx_func meson_g12a_aobus_functions[] = {
FUNCTION(i2c_ao_slave),
FUNCTION(remote_ao_input),
FUNCTION(remote_ao_out),
FUNCTION(pwm_a_e),
FUNCTION(pwm_ao_a),
FUNCTION(pwm_ao_b),
FUNCTION(pwm_ao_c),
......
......@@ -192,8 +192,8 @@ static const unsigned int uart_rts_b_pins[] = { GPIODV_27 };
static const unsigned int uart_tx_c_pins[] = { GPIOY_13 };
static const unsigned int uart_rx_c_pins[] = { GPIOY_14 };
static const unsigned int uart_cts_c_pins[] = { GPIOX_11 };
static const unsigned int uart_rts_c_pins[] = { GPIOX_12 };
static const unsigned int uart_cts_c_pins[] = { GPIOY_11 };
static const unsigned int uart_rts_c_pins[] = { GPIOY_12 };
static const unsigned int i2c_sck_a_pins[] = { GPIODV_25 };
static const unsigned int i2c_sda_a_pins[] = { GPIODV_24 };
......@@ -439,10 +439,10 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = {
GROUP(pwm_f_x, 3, 18),
/* Bank Y */
GROUP(uart_cts_c, 1, 19),
GROUP(uart_rts_c, 1, 18),
GROUP(uart_tx_c, 1, 17),
GROUP(uart_rx_c, 1, 16),
GROUP(uart_cts_c, 1, 17),
GROUP(uart_rts_c, 1, 16),
GROUP(uart_tx_c, 1, 19),
GROUP(uart_rx_c, 1, 18),
GROUP(pwm_a_y, 1, 21),
GROUP(pwm_f_y, 1, 20),
GROUP(i2s_out_ch23_y, 1, 5),
......
......@@ -651,6 +651,7 @@ static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
continue;
if (gpio_np) {
dev_err(pc->dev, "multiple gpio nodes\n");
of_node_put(np);
return -EINVAL;
}
gpio_np = np;
......
......@@ -32,6 +32,7 @@ enum {
V_ARMADA_7K = BIT(0),
V_ARMADA_8K_CPM = BIT(1),
V_ARMADA_8K_CPS = BIT(2),
V_CP115_STANDALONE = BIT(3),
V_ARMADA_7K_8K_CPM = (V_ARMADA_7K | V_ARMADA_8K_CPM),
V_ARMADA_7K_8K_CPS = (V_ARMADA_7K | V_ARMADA_8K_CPS),
};
......@@ -597,7 +598,8 @@ static struct mvebu_mpp_mode armada_cp110_mpp_modes[] = {
MPP_FUNCTION(7, "uart0", "rxd"),
MPP_FUNCTION(8, "uart2", "rxd"),
MPP_FUNCTION(9, "sata0", "present_act"),
MPP_FUNCTION(10, "ge", "mdc")),
MPP_FUNCTION(10, "ge", "mdc"),
MPP_FUNCTION(14, "sdio", "ds")),
};
static const struct of_device_id armada_cp110_pinctrl_of_match[] = {
......@@ -613,6 +615,10 @@ static const struct of_device_id armada_cp110_pinctrl_of_match[] = {
.compatible = "marvell,armada-8k-cps-pinctrl",
.data = (void *) V_ARMADA_8K_CPS,
},
{
.compatible = "marvell,cp115-standalone-pinctrl",
.data = (void *) V_CP115_STANDALONE,
},
{ },
};
......@@ -654,16 +660,20 @@ static int armada_cp110_pinctrl_probe(struct platform_device *pdev)
switch (i) {
case 0 ... 31:
mvebu_pinctrl_assign_variant(m, V_ARMADA_7K_8K_CPS);
mvebu_pinctrl_assign_variant(m, (V_ARMADA_7K_8K_CPS |
V_CP115_STANDALONE));
break;
case 32 ... 38:
mvebu_pinctrl_assign_variant(m, V_ARMADA_7K_8K_CPM);
mvebu_pinctrl_assign_variant(m, (V_ARMADA_7K_8K_CPM |
V_CP115_STANDALONE));
break;
case 39 ... 43:
mvebu_pinctrl_assign_variant(m, V_ARMADA_8K_CPM);
mvebu_pinctrl_assign_variant(m, (V_ARMADA_8K_CPM |
V_CP115_STANDALONE));
break;
case 44 ... 62:
mvebu_pinctrl_assign_variant(m, V_ARMADA_7K_8K_CPM);
mvebu_pinctrl_assign_variant(m, (V_ARMADA_7K_8K_CPM |
V_CP115_STANDALONE));
break;
}
}
......
......@@ -815,6 +815,7 @@ static int abx500_dt_node_to_map(struct pinctrl_dev *pctldev,
&reserved_maps, num_maps);
if (ret < 0) {
pinctrl_utils_free_map(pctldev, *map, *num_maps);
of_node_put(np);
return ret;
}
}
......
......@@ -1508,6 +1508,7 @@ static int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
&reserved_maps, num_maps);
if (ret < 0) {
pinctrl_utils_free_map(pctldev, *map, *num_maps);
of_node_put(np);
return ret;
}
}
......
......@@ -565,15 +565,25 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
!(regval & BIT(INTERRUPT_MASK_OFF)))
continue;
irq = irq_find_mapping(gc->irq.domain, irqnr + i);
generic_handle_irq(irq);
if (irq != 0)
generic_handle_irq(irq);
/* Clear interrupt.
* We must read the pin register again, in case the
* value was changed while executing
* generic_handle_irq() above.
* If we didn't find a mapping for the interrupt,
* disable it in order to avoid a system hang caused
* by an interrupt storm.
*/
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
regval = readl(regs + i);
if (irq == 0) {
regval &= ~BIT(INTERRUPT_ENABLE_OFF);
dev_dbg(&gpio_dev->pdev->dev,
"Disabling spurious GPIO IRQ %d\n",
irqnr + i);
}
writel(regval, regs + i);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
ret = IRQ_HANDLED;
......@@ -861,10 +871,8 @@ static int amd_gpio_probe(struct platform_device *pdev)
return -ENOMEM;
irq_base = platform_get_irq(pdev, 0);
if (irq_base < 0) {
dev_err(&pdev->dev, "Failed to get gpio IRQ: %d\n", irq_base);
if (irq_base < 0)
return irq_base;
}
#ifdef CONFIG_PM_SLEEP
gpio_dev->saved_regs = devm_kcalloc(&pdev->dev, amd_pinctrl_desc.npins,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -2222,10 +2222,8 @@ static int pic32_gpio_probe(struct platform_device *pdev)
return PTR_ERR(bank->reg_base);
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "irq get failed\n");
if (irq < 0)
return irq;
}
bank->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(bank->clk)) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment