提交 cf0c97f1 编写于 作者: L Linus Torvalds

Merge tag 'pinctrl-v5.8-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.8 kernel cycle.

  It's just really boring this time. Zero core changes. Just linear
  development, cleanups and misc noncritical fixes. Some new drivers for
  very new Qualcomm and Intel chips.

  New drivers:

   - Intel Jasper Lake support.

   - NXP Freescale i.MX8DXL support.

   - Qualcomm SM8250 support.

   - Renesas R8A7742 SH-PFC support.

  Driver improvements:

   - Severe cleanup and modernization of the MCP23s08 driver.

   - Mediatek driver modularized.

   - Setting config supported in the Meson driver.

   - Wakeup support for the Broadcom BCM7211"

* tag 'pinctrl-v5.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (72 commits)
  pinctrl: sprd: Fix the incorrect pull-up definition
  pinctrl: pxa: pxa2xx: Remove 'pxa2xx_pinctrl_exit()' which is unused and broken
  pinctrl: freescale: imx: Use 'devm_of_iomap()' to avoid a resource leak in case of error in 'imx_pinctrl_probe()'
  pinctrl: freescale: imx: Fix an error handling path in 'imx_pinctrl_probe()'
  pinctrl: sirf: add missing put_device() call in sirfsoc_gpio_probe()
  pinctrl: imxl: Fix an error handling path in 'imx1_pinctrl_core_probe()'
  pinctrl: bcm2835: Add support for wake-up interrupts
  pinctrl: bcm2835: Match BCM7211 compatible string
  dt-bindings: pinctrl: Document optional BCM7211 wake-up interrupts
  dt-bindings: pinctrl: Document 7211 compatible for brcm, bcm2835-gpio.txt
  dt-bindings: pinctrl: stm32: Add missing interrupts property
  pinctrl: at91-pio4: Add COMPILE_TEST support
  pinctrl: Fix return value about devm_platform_ioremap_resource()
  MAINTAINERS: Renesas Pin Controllers are supported
  dt-bindings: pinctrl: ocelot: Add Sparx5 SoC support
  pinctrl: ocelot: Fix GPIO interrupt decoding on Jaguar2
  pinctrl: ocelot: Remove instance number from pin functions
  pinctrl: ocelot: Always register GPIO driver
  dt-bindings: pinctrl: rockchip: update example
  pinctrl: amd: Add ACPI dependency
  ...
......@@ -108,7 +108,8 @@ This binding uses the i.MX common pinctrl binding[3].
Required properties:
- compatible: Should be one of:
"fsl,imx8qm-iomuxc",
"fsl,imx8qxp-iomuxc".
"fsl,imx8qxp-iomuxc",
"fsl,imx8dxl-iomuxc".
Required properties for Pinctrl sub nodes:
- fsl,pins: Each entry consists of 3 integers which represents
......@@ -116,7 +117,8 @@ Required properties for Pinctrl sub nodes:
integers <pin_id mux_mode> are specified using a
PIN_FUNC_ID macro, which can be found in
<dt-bindings/pinctrl/pads-imx8qm.h>,
<dt-bindings/pinctrl/pads-imx8qxp.h>.
<dt-bindings/pinctrl/pads-imx8qxp.h>,
<dt-bindings/pinctrl/pads-imx8dxl.h>.
The last integer CONFIG is the pad setting value like
pull-up on this pin.
......
......@@ -9,13 +9,16 @@ Required properties:
"brcm,bcm2835-gpio" - BCM2835 compatible pinctrl
"brcm,bcm7211-gpio" - BCM7211 compatible pinctrl
"brcm,bcm2711-gpio" - BCM2711 compatible pinctrl
"brcm,bcm7211-gpio" - BCM7211 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
second cell is used to specify optional parameters:
- bit 0 specifies polarity (0 for normal, 1 for inverted)
- interrupts : The interrupt outputs from the controller. One interrupt per
individual bank followed by the "all banks" interrupt.
individual bank followed by the "all banks" interrupt. For BCM7211, an
additional set of per-bank interrupt line and an "all banks" wake-up
interrupt may be specified.
- interrupt-controller: Marks the device node as an interrupt controller.
- #interrupt-cells : Should be 2.
The first cell is the GPIO number.
......
......@@ -2,8 +2,8 @@ Microsemi Ocelot pin controller Device Tree Bindings
----------------------------------------------------
Required properties:
- compatible : Should be "mscc,ocelot-pinctrl" or
"mscc,jaguar2-pinctrl"
- compatible : Should be "mscc,ocelot-pinctrl",
"mscc,jaguar2-pinctrl" or "microchip,sparx5-pinctrl"
- reg : Address and length of the register set for the device
- gpio-controller : Indicates this device is a GPIO controller
- #gpio-cells : Must be 2.
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/qcom,sm8250-pinctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Technologies, Inc. SM8250 TLMM block
maintainers:
- Bjorn Andersson <bjorn.andersson@linaro.org>
description: |
This binding describes the Top Level Mode Multiplexer block found in the
SM8250 platform.
properties:
compatible:
const: qcom,sm8250-pinctrl
reg:
minItems: 3
maxItems: 3
reg-names:
items:
- const: "west"
- const: "south"
- const: "north"
interrupts:
description: Specifies the TLMM summary IRQ
maxItems: 1
interrupt-controller: true
'#interrupt-cells':
description:
Specifies the PIN numbers and Flags, as defined in defined in
include/dt-bindings/interrupt-controller/irq.h
const: 2
gpio-controller: true
'#gpio-cells':
description: Specifying the pin number and flags, as defined in
include/dt-bindings/gpio/gpio.h
const: 2
gpio-ranges:
maxItems: 1
wakeup-parent:
maxItems: 1
#PIN CONFIGURATION NODES
patternProperties:
'^.*$':
if:
type: object
then:
properties:
pins:
description:
List of gpio pins affected by the properties specified in this
subnode.
items:
oneOf:
- pattern: "^gpio([0-9]|[1-9][0-9]|1[0-7][0-9])$"
- enum: [ sdc2_clk, sdc2_cmd, sdc2_data, ufs_reset ]
minItems: 1
maxItems: 36
function:
description:
Specify the alternative function to be configured for the specified
pins.
enum: [ aoss_cti, atest, audio_ref, cam_mclk, cci_async, cci_i2c,
cci_timer0, cci_timer1, cci_timer2, cci_timer3, cci_timer4, cri_trng,
cri_trng0, cri_trng1, dbg_out, ddr_bist, ddr_pxi0, ddr_pxi1,
ddr_pxi2, ddr_pxi3, dp_hot, dp_lcd, gcc_gp1, gcc_gp2, gcc_gp3, gpio,
ibi_i3c, jitter_bist, lpass_slimbus, mdp_vsync, mdp_vsync0,
mdp_vsync1, mdp_vsync2, mdp_vsync3, mi2s0_data0, mi2s0_data1,
mi2s0_sck, mi2s0_ws, mi2s1_data0, mi2s1_data1, mi2s1_sck, mi2s1_ws,
mi2s2_data0, mi2s2_data1, mi2s2_sck, mi2s2_ws, pci_e0, pci_e1,
pci_e2, phase_flag, pll_bist, pll_bypassnl, pll_clk, pll_reset,
pri_mi2s, prng_rosc, qdss_cti, qdss_gpio, qspi0, qspi1, qspi2, qspi3,
qspi_clk, qspi_cs, qup0, qup1, qup10, qup11, qup12, qup13, qup14,
qup15, qup16, qup17, qup18, qup19, qup2, qup3, qup4, qup5, qup6,
qup7, qup8, qup9, qup_l4, qup_l5, qup_l6, sd_write, sdc40, sdc41,
sdc42, sdc43, sdc4_clk, sdc4_cmd, sec_mi2s, sp_cmu, tgu_ch0, tgu_ch1,
tgu_ch2, tgu_ch3, tsense_pwm1, tsense_pwm2, tsif0_clk, tsif0_data,
tsif0_en, tsif0_error, tsif0_sync, tsif1_clk, tsif1_data, tsif1_en,
tsif1_error, tsif1_sync, usb2phy_ac, usb_phy, vsense_trigger ]
drive-strength:
enum: [2, 4, 6, 8, 10, 12, 14, 16]
default: 2
description:
Selects the drive strength for the specified pins, in mA.
bias-pull-down: true
bias-pull-up: true
bias-disable: true
output-high: true
output-low: true
required:
- pins
- function
additionalProperties: false
required:
- compatible
- reg
- reg-names
- interrupts
- interrupt-controller
- '#interrupt-cells'
- gpio-controller
- '#gpio-cells'
- gpio-ranges
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
pinctrl@1f00000 {
compatible = "qcom,sm8250-pinctrl";
reg = <0x0f100000 0x300000>,
<0x0f500000 0x300000>,
<0x0f900000 0x300000>;
reg-names = "west", "south", "north";
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
gpio-ranges = <&tlmm 0 0 180>;
wakeup-parent = <&pdc>;
};
......@@ -13,6 +13,7 @@ Required Properties:
- "renesas,pfc-emev2": for EMEV2 (EMMA Mobile EV2) compatible pin-controller.
- "renesas,pfc-r8a73a4": for R8A73A4 (R-Mobile APE6) compatible pin-controller.
- "renesas,pfc-r8a7740": for R8A7740 (R-Mobile A1) compatible pin-controller.
- "renesas,pfc-r8a7742": for R8A7742 (RZ/G1H) compatible pin-controller.
- "renesas,pfc-r8a7743": for R8A7743 (RZ/G1M) compatible pin-controller.
- "renesas,pfc-r8a7744": for R8A7744 (RZ/G1N) compatible pin-controller.
- "renesas,pfc-r8a7745": for R8A7745 (RZ/G1E) compatible pin-controller.
......
......@@ -110,8 +110,8 @@ pinctrl@20008000 {
uart2 {
uart2_xfer: uart2-xfer {
rockchip,pins = <RK_GPIO1 8 1 &pcfg_pull_default>,
<RK_GPIO1 9 1 &pcfg_pull_default>;
rockchip,pins = <1 RK_PB0 1 &pcfg_pull_default>,
<1 RK_PB1 1 &pcfg_pull_default>;
};
};
};
......
......@@ -36,6 +36,9 @@ properties:
pins-are-numbered: true
hwlocks: true
interrupts:
maxItems: 1
st,syscfg:
description: Should be phandle/offset/mask
- Phandle to the syscon node which includes IRQ mux selection.
......
......@@ -13496,8 +13496,9 @@ F: drivers/pinctrl/qcom/
PIN CONTROLLER - RENESAS
M: Geert Uytterhoeven <geert+renesas@glider.be>
L: linux-renesas-soc@vger.kernel.org
S: Maintained
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git sh-pfc
F: Documentation/devicetree/bindings/pinctrl/renesas,*
F: drivers/pinctrl/pinctrl-rz*
F: drivers/pinctrl/sh-pfc/
......
......@@ -82,7 +82,7 @@ config PINCTRL_AT91
config PINCTRL_AT91PIO4
bool "AT91 PIO4 pinctrl driver"
depends on OF
depends on ARCH_AT91
depends on ARCH_AT91 || COMPILE_TEST
select PINMUX
select GENERIC_PINCONF
select GPIOLIB
......@@ -95,6 +95,7 @@ config PINCTRL_AT91PIO4
config PINCTRL_AMD
tristate "AMD GPIO pin control"
depends on HAS_IOMEM
depends on ACPI || COMPILE_TEST
select GPIOLIB
select GPIOLIB_IRQCHIP
select PINMUX
......@@ -172,15 +173,22 @@ config PINCTRL_GEMINI
select GENERIC_PINCONF
select MFD_SYSCON
config PINCTRL_MCP23S08_I2C
tristate
select REGMAP_I2C
config PINCTRL_MCP23S08_SPI
tristate
select REGMAP_SPI
config PINCTRL_MCP23S08
tristate "Microchip MCP23xxx I/O expander"
depends on SPI_MASTER || I2C
depends on I2C || I2C=n
select GPIOLIB
select GPIOLIB_IRQCHIP
select REGMAP_I2C if I2C
select REGMAP_SPI if SPI_MASTER
select GENERIC_PINCONF
select PINCTRL_MCP23S08_I2C if I2C
select PINCTRL_MCP23S08_SPI if SPI_MASTER
help
SPI/I2C driver for Microchip MCP23S08 / MCP23S17 / MCP23S18 /
MCP23008 / MCP23017 / MCP23018 I/O expanders.
......@@ -435,6 +443,7 @@ config PINCTRL_TB10X
config PINCTRL_EQUILIBRIUM
tristate "Generic pinctrl and GPIO driver for Intel Lightning Mountain SoC"
depends on OF && HAS_IOMEM
depends on X86 || COMPILE_TEST
select PINMUX
select PINCONF
select GPIOLIB
......
......@@ -21,6 +21,8 @@ obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_GEMINI) += pinctrl-gemini.o
obj-$(CONFIG_PINCTRL_MAX77620) += pinctrl-max77620.o
obj-$(CONFIG_PINCTRL_MCP23S08_I2C) += pinctrl-mcp23s08_i2c.o
obj-$(CONFIG_PINCTRL_MCP23S08_SPI) += pinctrl-mcp23s08_spi.o
obj-$(CONFIG_PINCTRL_MCP23S08) += pinctrl-mcp23s08.o
obj-$(CONFIG_PINCTRL_MESON) += meson/
obj-$(CONFIG_PINCTRL_OXNAS) += pinctrl-oxnas.o
......
......@@ -1406,7 +1406,7 @@ static int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
pdata->reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pdata->reg_base)) {
dev_err(&pdev->dev, "Failed to ioremap MEM resource\n");
return -ENODEV;
return PTR_ERR(pdata->reg_base);
}
/* Initialize the dynamic part of pinctrl_desc */
......
......@@ -19,6 +19,7 @@
#include <linux/irq.h>
#include <linux/irqdesc.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/of_address.h>
#include <linux/of.h>
#include <linux/of_irq.h>
......@@ -76,6 +77,7 @@
struct bcm2835_pinctrl {
struct device *dev;
void __iomem *base;
int *wake_irq;
/* note: locking assumes each bank will have its own unsigned long */
unsigned long enabled_irq_map[BCM2835_NUM_BANKS];
......@@ -435,6 +437,11 @@ static void bcm2835_gpio_irq_handler(struct irq_desc *desc)
chained_irq_exit(host_chip, desc);
}
static irqreturn_t bcm2835_gpio_wake_irq_handler(int irq, void *dev_id)
{
return IRQ_HANDLED;
}
static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc,
unsigned reg, unsigned offset, bool enable)
{
......@@ -634,6 +641,34 @@ static void bcm2835_gpio_irq_ack(struct irq_data *data)
bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
}
static int bcm2835_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
unsigned gpio = irqd_to_hwirq(data);
unsigned int irqgroup;
int ret = -EINVAL;
if (!pc->wake_irq)
return ret;
if (gpio <= 27)
irqgroup = 0;
else if (gpio >= 28 && gpio <= 45)
irqgroup = 1;
else if (gpio >= 46 && gpio <= 57)
irqgroup = 2;
else
return ret;
if (on)
ret = enable_irq_wake(pc->wake_irq[irqgroup]);
else
ret = disable_irq_wake(pc->wake_irq[irqgroup]);
return ret;
}
static struct irq_chip bcm2835_gpio_irq_chip = {
.name = MODULE_NAME,
.irq_enable = bcm2835_gpio_irq_enable,
......@@ -642,6 +677,8 @@ static struct irq_chip bcm2835_gpio_irq_chip = {
.irq_ack = bcm2835_gpio_irq_ack,
.irq_mask = bcm2835_gpio_irq_disable,
.irq_unmask = bcm2835_gpio_irq_enable,
.irq_set_wake = bcm2835_gpio_irq_set_wake,
.flags = IRQCHIP_MASK_ON_SUSPEND,
};
static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev)
......@@ -1137,6 +1174,10 @@ static const struct of_device_id bcm2835_pinctrl_match[] = {
.compatible = "brcm,bcm2711-gpio",
.data = &bcm2711_plat_data,
},
{
.compatible = "brcm,bcm7211-gpio",
.data = &bcm2711_plat_data,
},
{}
};
......@@ -1150,6 +1191,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
struct resource iomem;
int err, i;
const struct of_device_id *match;
int is_7211 = 0;
BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2711_NUM_GPIOS);
BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2711_NUM_GPIOS);
......@@ -1176,6 +1218,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
return -EINVAL;
pdata = match->data;
is_7211 = of_device_is_compatible(np, "brcm,bcm7211-gpio");
pc->gpio_chip = *pdata->gpio_chip;
pc->gpio_chip.parent = dev;
......@@ -1210,6 +1253,15 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
if (is_7211) {
pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS,
sizeof(*pc->wake_irq),
GFP_KERNEL);
if (!pc->wake_irq)
return -ENOMEM;
}
/*
* Use the same handler for all groups: this is necessary
* since we use one gpiochip to cover all lines - the
......@@ -1217,8 +1269,34 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
* bank that was firing the IRQ and look up the per-group
* and bank data.
*/
for (i = 0; i < BCM2835_NUM_IRQS; i++)
for (i = 0; i < BCM2835_NUM_IRQS; i++) {
int len;
char *name;
girq->parents[i] = irq_of_parse_and_map(np, i);
if (!is_7211)
continue;
/* Skip over the all banks interrupts */
pc->wake_irq[i] = irq_of_parse_and_map(np, i +
BCM2835_NUM_IRQS + 1);
len = strlen(dev_name(pc->dev)) + 16;
name = devm_kzalloc(pc->dev, len, GFP_KERNEL);
if (!name)
return -ENOMEM;
snprintf(name, len, "%s:bank%d", dev_name(pc->dev), i);
/* These are optional interrupts */
err = devm_request_irq(dev, pc->wake_irq[i],
bcm2835_gpio_wake_irq_handler,
IRQF_SHARED, name, pc);
if (err)
dev_warn(dev, "unable to request wake IRQ %d\n",
pc->wake_irq[i]);
}
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;
......
......@@ -165,6 +165,13 @@ config PINCTRL_IMX8QXP
help
Say Y here to enable the imx8qxp pinctrl driver
config PINCTRL_IMX8DXL
bool "IMX8DXL pinctrl driver"
depends on IMX_SCU && ARCH_MXC && ARM64
select PINCTRL_IMX_SCU
help
Say Y here to enable the imx8dxl pinctrl driver
config PINCTRL_VF610
bool "Freescale Vybrid VF610 pinctrl driver"
depends on SOC_VF610
......
......@@ -24,6 +24,7 @@ obj-$(CONFIG_PINCTRL_IMX8MP) += pinctrl-imx8mp.o
obj-$(CONFIG_PINCTRL_IMX8MQ) += pinctrl-imx8mq.o
obj-$(CONFIG_PINCTRL_IMX8QM) += pinctrl-imx8qm.o
obj-$(CONFIG_PINCTRL_IMX8QXP) += pinctrl-imx8qxp.o
obj-$(CONFIG_PINCTRL_IMX8DXL) += pinctrl-imx8dxl.o
obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o
obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o
......
......@@ -774,16 +774,6 @@ static int imx_pinctrl_probe_dt(struct platform_device *pdev,
return 0;
}
/*
* imx_free_resources() - free memory used by this driver
* @info: info driver instance
*/
static void imx_free_resources(struct imx_pinctrl *ipctl)
{
if (ipctl->pctl)
pinctrl_unregister(ipctl->pctl);
}
int imx_pinctrl_probe(struct platform_device *pdev,
const struct imx_pinctrl_soc_info *info)
{
......@@ -834,12 +824,13 @@ int imx_pinctrl_probe(struct platform_device *pdev,
return -EINVAL;
}
ipctl->input_sel_base = of_iomap(np, 0);
ipctl->input_sel_base = devm_of_iomap(&pdev->dev, np,
0, NULL);
of_node_put(np);
if (!ipctl->input_sel_base) {
if (IS_ERR(ipctl->input_sel_base)) {
dev_err(&pdev->dev,
"iomuxc input select base address not found\n");
return -ENOMEM;
return PTR_ERR(ipctl->input_sel_base);
}
}
}
......@@ -874,23 +865,18 @@ int imx_pinctrl_probe(struct platform_device *pdev,
&ipctl->pctl);
if (ret) {
dev_err(&pdev->dev, "could not register IMX pinctrl driver\n");
goto free;
return ret;
}
ret = imx_pinctrl_probe_dt(pdev, ipctl);
if (ret) {
dev_err(&pdev->dev, "fail to probe dt properties\n");
goto free;
return ret;
}
dev_info(&pdev->dev, "initialized IMX pinctrl driver\n");
return pinctrl_enable(ipctl->pctl);
free:
imx_free_resources(ipctl);
return ret;
}
static int __maybe_unused imx_pinctrl_suspend(struct device *dev)
......
......@@ -60,7 +60,7 @@ struct imx1_pinctrl {
/*
* IMX1 IOMUXC manages the pins based on ports. Each port has 32 pins. IOMUX
* control register are seperated into function, output configuration, input
* control registers are separated into function, output configuration, input
* configuration A, input configuration B, GPIO in use and data direction.
*
* Those controls that are represented by 1 bit have a direct mapping between
......@@ -638,7 +638,6 @@ int imx1_pinctrl_core_probe(struct platform_device *pdev,
ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
if (ret) {
pinctrl_unregister(ipctl->pctl);
dev_err(&pdev->dev, "Failed to populate subdevices\n");
return ret;
}
......
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2019~2020 NXP
*/
#include <dt-bindings/pinctrl/pads-imx8dxl.h>
#include <linux/err.h>
#include <linux/firmware/imx/sci.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-imx.h"
static const struct pinctrl_pin_desc imx8dxl_pinctrl_pads[] = {
IMX_PINCTRL_PIN(IMX8DXL_PCIE_CTRL0_PERST_B),
IMX_PINCTRL_PIN(IMX8DXL_PCIE_CTRL0_CLKREQ_B),
IMX_PINCTRL_PIN(IMX8DXL_PCIE_CTRL0_WAKE_B),
IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_PCIESEP),
IMX_PINCTRL_PIN(IMX8DXL_USB_SS3_TC0),
IMX_PINCTRL_PIN(IMX8DXL_USB_SS3_TC1),
IMX_PINCTRL_PIN(IMX8DXL_USB_SS3_TC2),
IMX_PINCTRL_PIN(IMX8DXL_USB_SS3_TC3),
IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_3V3_USB3IO),
IMX_PINCTRL_PIN(IMX8DXL_EMMC0_CLK),
IMX_PINCTRL_PIN(IMX8DXL_EMMC0_CMD),
IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA0),
IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA1),
IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA2),
IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA3),
IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA4),
IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA5),
IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA6),
IMX_PINCTRL_PIN(IMX8DXL_EMMC0_DATA7),
IMX_PINCTRL_PIN(IMX8DXL_EMMC0_STROBE),
IMX_PINCTRL_PIN(IMX8DXL_EMMC0_RESET_B),
IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_SD1FIX0),
IMX_PINCTRL_PIN(IMX8DXL_USDHC1_RESET_B),
IMX_PINCTRL_PIN(IMX8DXL_USDHC1_VSELECT),
IMX_PINCTRL_PIN(IMX8DXL_CTL_NAND_RE_P_N),
IMX_PINCTRL_PIN(IMX8DXL_USDHC1_WP),
IMX_PINCTRL_PIN(IMX8DXL_USDHC1_CD_B),
IMX_PINCTRL_PIN(IMX8DXL_CTL_NAND_DQS_P_N),
IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_VSELSEP),
IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_TXC),
IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_TX_CTL),
IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_TXD0),
IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_TXD1),
IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_TXD2),
IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_TXD3),
IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0),
IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_RXC),
IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_RX_CTL),
IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_RXD0),
IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_RXD1),
IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_RXD2),
IMX_PINCTRL_PIN(IMX8DXL_ENET0_RGMII_RXD3),
IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1),
IMX_PINCTRL_PIN(IMX8DXL_ENET0_REFCLK_125M_25M),
IMX_PINCTRL_PIN(IMX8DXL_ENET0_MDIO),
IMX_PINCTRL_PIN(IMX8DXL_ENET0_MDC),
IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIOCT),
IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_TXC),
IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_TXD2),
IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_TX_CTL),
IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_TXD3),
IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_RXC),
IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_RXD3),
IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_RXD2),
IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_RXD1),
IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_TXD0),
IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_TXD1),
IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_RXD0),
IMX_PINCTRL_PIN(IMX8DXL_ENET1_RGMII_RX_CTL),
IMX_PINCTRL_PIN(IMX8DXL_ENET1_REFCLK_125M_25M),
IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHB),
IMX_PINCTRL_PIN(IMX8DXL_SPI3_SCK),
IMX_PINCTRL_PIN(IMX8DXL_SPI3_SDO),
IMX_PINCTRL_PIN(IMX8DXL_SPI3_SDI),
IMX_PINCTRL_PIN(IMX8DXL_SPI3_CS0),
IMX_PINCTRL_PIN(IMX8DXL_SPI3_CS1),
IMX_PINCTRL_PIN(IMX8DXL_MCLK_IN1),
IMX_PINCTRL_PIN(IMX8DXL_MCLK_IN0),
IMX_PINCTRL_PIN(IMX8DXL_MCLK_OUT0),
IMX_PINCTRL_PIN(IMX8DXL_UART1_TX),
IMX_PINCTRL_PIN(IMX8DXL_UART1_RX),
IMX_PINCTRL_PIN(IMX8DXL_UART1_RTS_B),
IMX_PINCTRL_PIN(IMX8DXL_UART1_CTS_B),
IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHK),
IMX_PINCTRL_PIN(IMX8DXL_SPI0_SCK),
IMX_PINCTRL_PIN(IMX8DXL_SPI0_SDI),
IMX_PINCTRL_PIN(IMX8DXL_SPI0_SDO),
IMX_PINCTRL_PIN(IMX8DXL_SPI0_CS1),
IMX_PINCTRL_PIN(IMX8DXL_SPI0_CS0),
IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHT),
IMX_PINCTRL_PIN(IMX8DXL_ADC_IN1),
IMX_PINCTRL_PIN(IMX8DXL_ADC_IN0),
IMX_PINCTRL_PIN(IMX8DXL_ADC_IN3),
IMX_PINCTRL_PIN(IMX8DXL_ADC_IN2),
IMX_PINCTRL_PIN(IMX8DXL_ADC_IN5),
IMX_PINCTRL_PIN(IMX8DXL_ADC_IN4),
IMX_PINCTRL_PIN(IMX8DXL_FLEXCAN0_RX),
IMX_PINCTRL_PIN(IMX8DXL_FLEXCAN0_TX),
IMX_PINCTRL_PIN(IMX8DXL_FLEXCAN1_RX),
IMX_PINCTRL_PIN(IMX8DXL_FLEXCAN1_TX),
IMX_PINCTRL_PIN(IMX8DXL_FLEXCAN2_RX),
IMX_PINCTRL_PIN(IMX8DXL_FLEXCAN2_TX),
IMX_PINCTRL_PIN(IMX8DXL_UART0_RX),
IMX_PINCTRL_PIN(IMX8DXL_UART0_TX),
IMX_PINCTRL_PIN(IMX8DXL_UART2_TX),
IMX_PINCTRL_PIN(IMX8DXL_UART2_RX),
IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIOLH),
IMX_PINCTRL_PIN(IMX8DXL_JTAG_TRST_B),
IMX_PINCTRL_PIN(IMX8DXL_PMIC_I2C_SCL),
IMX_PINCTRL_PIN(IMX8DXL_PMIC_I2C_SDA),
IMX_PINCTRL_PIN(IMX8DXL_PMIC_INT_B),
IMX_PINCTRL_PIN(IMX8DXL_SCU_GPIO0_00),
IMX_PINCTRL_PIN(IMX8DXL_SCU_GPIO0_01),
IMX_PINCTRL_PIN(IMX8DXL_SCU_PMIC_STANDBY),
IMX_PINCTRL_PIN(IMX8DXL_SCU_BOOT_MODE1),
IMX_PINCTRL_PIN(IMX8DXL_SCU_BOOT_MODE0),
IMX_PINCTRL_PIN(IMX8DXL_SCU_BOOT_MODE2),
IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_OUT1),
IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_OUT2),
IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_OUT3),
IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_OUT4),
IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_IN0),
IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_IN1),
IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_IN2),
IMX_PINCTRL_PIN(IMX8DXL_SNVS_TAMPER_IN3),
IMX_PINCTRL_PIN(IMX8DXL_SPI1_SCK),
IMX_PINCTRL_PIN(IMX8DXL_SPI1_SDO),
IMX_PINCTRL_PIN(IMX8DXL_SPI1_SDI),
IMX_PINCTRL_PIN(IMX8DXL_SPI1_CS0),
IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHD),
IMX_PINCTRL_PIN(IMX8DXL_QSPI0A_DATA1),
IMX_PINCTRL_PIN(IMX8DXL_QSPI0A_DATA0),
IMX_PINCTRL_PIN(IMX8DXL_QSPI0A_DATA3),
IMX_PINCTRL_PIN(IMX8DXL_QSPI0A_DATA2),
IMX_PINCTRL_PIN(IMX8DXL_QSPI0A_SS0_B),
IMX_PINCTRL_PIN(IMX8DXL_QSPI0A_DQS),
IMX_PINCTRL_PIN(IMX8DXL_QSPI0A_SCLK),
IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_QSPI0A),
IMX_PINCTRL_PIN(IMX8DXL_QSPI0B_SCLK),
IMX_PINCTRL_PIN(IMX8DXL_QSPI0B_DQS),
IMX_PINCTRL_PIN(IMX8DXL_QSPI0B_DATA1),
IMX_PINCTRL_PIN(IMX8DXL_QSPI0B_DATA0),
IMX_PINCTRL_PIN(IMX8DXL_QSPI0B_DATA3),
IMX_PINCTRL_PIN(IMX8DXL_QSPI0B_DATA2),
IMX_PINCTRL_PIN(IMX8DXL_QSPI0B_SS0_B),
IMX_PINCTRL_PIN(IMX8DXL_COMP_CTL_GPIO_1V8_3V3_QSPI0B)
};
static struct imx_pinctrl_soc_info imx8dxl_pinctrl_info = {
.pins = imx8dxl_pinctrl_pads,
.npins = ARRAY_SIZE(imx8dxl_pinctrl_pads),
.flags = IMX_USE_SCU,
};
static const struct of_device_id imx8dxl_pinctrl_of_match[] = {
{ .compatible = "fsl,imx8dxl-iomuxc", },
{ /* sentinel */ }
};
static int imx8dxl_pinctrl_probe(struct platform_device *pdev)
{
int ret;
ret = imx_pinctrl_sc_ipc_init(pdev);
if (ret)
return ret;
return imx_pinctrl_probe(pdev, &imx8dxl_pinctrl_info);
}
static struct platform_driver imx8dxl_pinctrl_driver = {
.driver = {
.name = "fsl,imx8dxl-iomuxc",
.of_match_table = of_match_ptr(imx8dxl_pinctrl_of_match),
.suppress_bind_attrs = true,
},
.probe = imx8dxl_pinctrl_probe,
};
static int __init imx8dxl_pinctrl_init(void)
{
return platform_driver_register(&imx8dxl_pinctrl_driver);
}
arch_initcall(imx8dxl_pinctrl_init);
......@@ -111,6 +111,14 @@ config PINCTRL_ICELAKE
This pinctrl driver provides an interface that allows configuring
of Intel Ice Lake PCH pins and using them as GPIOs.
config PINCTRL_JASPERLAKE
tristate "Intel Jasper Lake PCH pinctrl and GPIO driver"
depends on ACPI
select PINCTRL_INTEL
help
This pinctrl driver provides an interface that allows configuring
of Intel Jasper Lake PCH pins and using them as GPIOs.
config PINCTRL_LEWISBURG
tristate "Intel Lewisburg pinctrl and GPIO driver"
depends on ACPI
......
......@@ -12,6 +12,7 @@ obj-$(CONFIG_PINCTRL_CEDARFORK) += pinctrl-cedarfork.o
obj-$(CONFIG_PINCTRL_DENVERTON) += pinctrl-denverton.o
obj-$(CONFIG_PINCTRL_GEMINILAKE) += pinctrl-geminilake.o
obj-$(CONFIG_PINCTRL_ICELAKE) += pinctrl-icelake.o
obj-$(CONFIG_PINCTRL_JASPERLAKE) += pinctrl-jasperlake.o
obj-$(CONFIG_PINCTRL_LEWISBURG) += pinctrl-lewisburg.o
obj-$(CONFIG_PINCTRL_SUNRISEPOINT) += pinctrl-sunrisepoint.o
obj-$(CONFIG_PINCTRL_TIGERLAKE) += pinctrl-tigerlake.o
......@@ -1506,8 +1506,7 @@ static int byt_gpio_probe(struct intel_pinctrl *vg)
{
struct platform_device *pdev = to_platform_device(vg->dev);
struct gpio_chip *gc;
struct resource *irq_rc;
int ret;
int irq, ret;
/* Set up gpio chip */
vg->chip = byt_gpio_chip;
......@@ -1527,8 +1526,8 @@ static int byt_gpio_probe(struct intel_pinctrl *vg)
#endif
/* set up interrupts */
irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (irq_rc && irq_rc->start) {
irq = platform_get_irq_optional(pdev, 0);
if (irq > 0) {
struct gpio_irq_chip *girq;
vg->irqchip.name = "BYT-GPIO",
......@@ -1548,7 +1547,7 @@ static int byt_gpio_probe(struct intel_pinctrl *vg)
sizeof(*girq->parents), GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
girq->parents[0] = (unsigned int)irq_rc->start;
girq->parents[0] = irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_bad_irq;
}
......
......@@ -30,8 +30,6 @@
.gpio_base = (g), \
}
#define CNL_NO_GPIO -1
#define CNL_COMMUNITY(b, s, e, o, g) \
{ \
.barno = (b), \
......@@ -377,27 +375,27 @@ static const struct intel_padgroup cnlh_community0_gpps[] = {
};
static const struct intel_padgroup cnlh_community1_gpps[] = {
CNL_GPP(0, 51, 74, 64), /* GPP_C */
CNL_GPP(1, 75, 98, 96), /* GPP_D */
CNL_GPP(2, 99, 106, 128), /* GPP_G */
CNL_GPP(3, 107, 114, CNL_NO_GPIO), /* AZA */
CNL_GPP(4, 115, 146, 160), /* vGPIO_0 */
CNL_GPP(5, 147, 154, CNL_NO_GPIO), /* vGPIO_1 */
CNL_GPP(0, 51, 74, 64), /* GPP_C */
CNL_GPP(1, 75, 98, 96), /* GPP_D */
CNL_GPP(2, 99, 106, 128), /* GPP_G */
CNL_GPP(3, 107, 114, INTEL_GPIO_BASE_NOMAP), /* AZA */
CNL_GPP(4, 115, 146, 160), /* vGPIO_0 */
CNL_GPP(5, 147, 154, INTEL_GPIO_BASE_NOMAP), /* vGPIO_1 */
};
static const struct intel_padgroup cnlh_community3_gpps[] = {
CNL_GPP(0, 155, 178, 192), /* GPP_K */
CNL_GPP(1, 179, 202, 224), /* GPP_H */
CNL_GPP(2, 203, 215, 256), /* GPP_E */
CNL_GPP(3, 216, 239, 288), /* GPP_F */
CNL_GPP(4, 240, 248, CNL_NO_GPIO), /* SPI */
CNL_GPP(0, 155, 178, 192), /* GPP_K */
CNL_GPP(1, 179, 202, 224), /* GPP_H */
CNL_GPP(2, 203, 215, 256), /* GPP_E */
CNL_GPP(3, 216, 239, 288), /* GPP_F */
CNL_GPP(4, 240, 248, INTEL_GPIO_BASE_NOMAP), /* SPI */
};
static const struct intel_padgroup cnlh_community4_gpps[] = {
CNL_GPP(0, 249, 259, CNL_NO_GPIO), /* CPU */
CNL_GPP(1, 260, 268, CNL_NO_GPIO), /* JTAG */
CNL_GPP(2, 269, 286, 320), /* GPP_I */
CNL_GPP(3, 287, 298, 352), /* GPP_J */
CNL_GPP(0, 249, 259, INTEL_GPIO_BASE_NOMAP), /* CPU */
CNL_GPP(1, 260, 268, INTEL_GPIO_BASE_NOMAP), /* JTAG */
CNL_GPP(2, 269, 286, 320), /* GPP_I */
CNL_GPP(3, 287, 298, 352), /* GPP_J */
};
static const unsigned int cnlh_spi0_pins[] = { 40, 41, 42, 43 };
......@@ -790,25 +788,25 @@ static const struct intel_function cnllp_functions[] = {
};
static const struct intel_padgroup cnllp_community0_gpps[] = {
CNL_GPP(0, 0, 24, 0), /* GPP_A */
CNL_GPP(1, 25, 50, 32), /* GPP_B */
CNL_GPP(2, 51, 58, 64), /* GPP_G */
CNL_GPP(3, 59, 67, CNL_NO_GPIO), /* SPI */
CNL_GPP(0, 0, 24, 0), /* GPP_A */
CNL_GPP(1, 25, 50, 32), /* GPP_B */
CNL_GPP(2, 51, 58, 64), /* GPP_G */
CNL_GPP(3, 59, 67, INTEL_GPIO_BASE_NOMAP), /* SPI */
};
static const struct intel_padgroup cnllp_community1_gpps[] = {
CNL_GPP(0, 68, 92, 96), /* GPP_D */
CNL_GPP(1, 93, 116, 128), /* GPP_F */
CNL_GPP(2, 117, 140, 160), /* GPP_H */
CNL_GPP(3, 141, 172, 192), /* vGPIO */
CNL_GPP(4, 173, 180, 224), /* vGPIO */
CNL_GPP(0, 68, 92, 96), /* GPP_D */
CNL_GPP(1, 93, 116, 128), /* GPP_F */
CNL_GPP(2, 117, 140, 160), /* GPP_H */
CNL_GPP(3, 141, 172, 192), /* vGPIO */
CNL_GPP(4, 173, 180, 224), /* vGPIO */
};
static const struct intel_padgroup cnllp_community4_gpps[] = {
CNL_GPP(0, 181, 204, 256), /* GPP_C */
CNL_GPP(1, 205, 228, 288), /* GPP_E */
CNL_GPP(2, 229, 237, CNL_NO_GPIO), /* JTAG */
CNL_GPP(3, 238, 243, CNL_NO_GPIO), /* HVCMOS */
CNL_GPP(0, 181, 204, 256), /* GPP_C */
CNL_GPP(1, 205, 228, 288), /* GPP_E */
CNL_GPP(2, 229, 237, INTEL_GPIO_BASE_NOMAP), /* JTAG */
CNL_GPP(3, 238, 243, INTEL_GPIO_BASE_NOMAP), /* HVCMOS */
};
static const struct intel_community cnllp_communities[] = {
......
......@@ -35,18 +35,18 @@
#define CHV_PADCTRL0 0x000
#define CHV_PADCTRL0_INTSEL_SHIFT 28
#define CHV_PADCTRL0_INTSEL_MASK (0xf << CHV_PADCTRL0_INTSEL_SHIFT)
#define CHV_PADCTRL0_INTSEL_MASK GENMASK(31, 28)
#define CHV_PADCTRL0_TERM_UP BIT(23)
#define CHV_PADCTRL0_TERM_SHIFT 20
#define CHV_PADCTRL0_TERM_MASK (7 << CHV_PADCTRL0_TERM_SHIFT)
#define CHV_PADCTRL0_TERM_MASK GENMASK(22, 20)
#define CHV_PADCTRL0_TERM_20K 1
#define CHV_PADCTRL0_TERM_5K 2
#define CHV_PADCTRL0_TERM_1K 4
#define CHV_PADCTRL0_PMODE_SHIFT 16
#define CHV_PADCTRL0_PMODE_MASK (0xf << CHV_PADCTRL0_PMODE_SHIFT)
#define CHV_PADCTRL0_PMODE_MASK GENMASK(19, 16)
#define CHV_PADCTRL0_GPIOEN BIT(15)
#define CHV_PADCTRL0_GPIOCFG_SHIFT 8
#define CHV_PADCTRL0_GPIOCFG_MASK (7 << CHV_PADCTRL0_GPIOCFG_SHIFT)
#define CHV_PADCTRL0_GPIOCFG_MASK GENMASK(10, 8)
#define CHV_PADCTRL0_GPIOCFG_GPIO 0
#define CHV_PADCTRL0_GPIOCFG_GPO 1
#define CHV_PADCTRL0_GPIOCFG_GPI 2
......@@ -57,57 +57,16 @@
#define CHV_PADCTRL1 0x004
#define CHV_PADCTRL1_CFGLOCK BIT(31)
#define CHV_PADCTRL1_INVRXTX_SHIFT 4
#define CHV_PADCTRL1_INVRXTX_MASK (0xf << CHV_PADCTRL1_INVRXTX_SHIFT)
#define CHV_PADCTRL1_INVRXTX_TXENABLE (2 << CHV_PADCTRL1_INVRXTX_SHIFT)
#define CHV_PADCTRL1_INVRXTX_MASK GENMASK(7, 4)
#define CHV_PADCTRL1_INVRXTX_RXDATA BIT(6)
#define CHV_PADCTRL1_INVRXTX_TXENABLE BIT(5)
#define CHV_PADCTRL1_ODEN BIT(3)
#define CHV_PADCTRL1_INVRXTX_RXDATA (4 << CHV_PADCTRL1_INVRXTX_SHIFT)
#define CHV_PADCTRL1_INTWAKECFG_MASK 7
#define CHV_PADCTRL1_INTWAKECFG_MASK GENMASK(2, 0)
#define CHV_PADCTRL1_INTWAKECFG_FALLING 1
#define CHV_PADCTRL1_INTWAKECFG_RISING 2
#define CHV_PADCTRL1_INTWAKECFG_BOTH 3
#define CHV_PADCTRL1_INTWAKECFG_LEVEL 4
/**
* struct chv_alternate_function - A per group or per pin alternate function
* @pin: Pin number (only used in per pin configs)
* @mode: Mode the pin should be set in
* @invert_oe: Invert OE for this pin
*/
struct chv_alternate_function {
unsigned int pin;
u8 mode;
bool invert_oe;
};
/**
* struct chv_pincgroup - describes a CHV pin group
* @name: Name of the group
* @pins: An array of pins in this group
* @npins: Number of pins in this group
* @altfunc: Alternate function applied to all pins in this group
* @overrides: Alternate function override per pin or %NULL if not used
* @noverrides: Number of per pin alternate function overrides if
* @overrides != NULL.
*/
struct chv_pingroup {
const char *name;
const unsigned int *pins;
size_t npins;
struct chv_alternate_function altfunc;
const struct chv_alternate_function *overrides;
size_t noverrides;
};
/**
* struct chv_gpio_pinrange - A range of pins that can be used as GPIOs
* @base: Start pin number
* @npins: Number of pins in this range
*/
struct chv_gpio_pinrange {
unsigned int base;
unsigned int npins;
};
/**
* struct chv_community - A community specific configuration
* @uid: ACPI _UID used to match the community
......@@ -117,8 +76,8 @@ struct chv_gpio_pinrange {
* @ngroups: Number of groups
* @functions: All functions in this community
* @nfunctions: Number of functions
* @gpio_ranges: An array of GPIO ranges in this community
* @ngpio_ranges: Number of GPIO ranges
* @gpps: Pad groups
* @ngpps: Number of pad groups in this community
* @nirqs: Total number of IRQs this community can generate
* @acpi_space_id: An address space ID for ACPI OpRegion handler
*/
......@@ -126,12 +85,12 @@ struct chv_community {
const char *uid;
const struct pinctrl_pin_desc *pins;
size_t npins;
const struct chv_pingroup *groups;
const struct intel_pingroup *groups;
size_t ngroups;
const struct intel_function *functions;
size_t nfunctions;
const struct chv_gpio_pinrange *gpio_ranges;
size_t ngpio_ranges;
const struct intel_padgroup *gpps;
size_t ngpps;
size_t nirqs;
acpi_adr_space_type acpi_space_id;
};
......@@ -173,37 +132,14 @@ struct chv_pinctrl {
struct chv_pin_context *saved_pin_context;
};
#define ALTERNATE_FUNCTION(p, m, i) \
{ \
.pin = (p), \
.mode = (m), \
.invert_oe = (i), \
}
#define PINMODE_INVERT_OE BIT(15)
#define PIN_GROUP_WITH_ALT(n, p, m, i) \
{ \
.name = (n), \
.pins = (p), \
.npins = ARRAY_SIZE((p)), \
.altfunc.mode = (m), \
.altfunc.invert_oe = (i), \
}
#define PINMODE(m, i) ((m) | ((i) * PINMODE_INVERT_OE))
#define PIN_GROUP_WITH_OVERRIDE(n, p, m, i, o) \
{ \
.name = (n), \
.pins = (p), \
.npins = ARRAY_SIZE((p)), \
.altfunc.mode = (m), \
.altfunc.invert_oe = (i), \
.overrides = (o), \
.noverrides = ARRAY_SIZE((o)), \
}
#define GPIO_PINRANGE(start, end) \
#define CHV_GPP(start, end) \
{ \
.base = (start), \
.npins = (end) - (start) + 1, \
.size = (end) - (start) + 1, \
}
static const struct pinctrl_pin_desc southwest_pins[] = {
......@@ -288,40 +224,37 @@ static const unsigned southwest_i2c6_pins[] = { 47, 51 };
static const unsigned southwest_i2c_nfc_pins[] = { 49, 52 };
static const unsigned southwest_spi3_pins[] = { 76, 79, 80, 81, 82 };
/* LPE I2S TXD pins need to have invert_oe set */
static const struct chv_alternate_function southwest_lpe_altfuncs[] = {
ALTERNATE_FUNCTION(30, 1, true),
ALTERNATE_FUNCTION(34, 1, true),
ALTERNATE_FUNCTION(97, 1, true),
/* Some of LPE I2S TXD pins need to have OE inversion set */
static const unsigned int southwest_lpe_altfuncs[] = {
PINMODE(1, 1), PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 0), /* 30, 31, 32, 33 */
PINMODE(1, 1), PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 0), /* 34, 35, 36, 37 */
PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 1), /* 92, 94, 96, 97 */
};
/*
* Two spi3 chipselects are available in different mode than the main spi3
* functionality, which is using mode 1.
* functionality, which is using mode 2.
*/
static const struct chv_alternate_function southwest_spi3_altfuncs[] = {
ALTERNATE_FUNCTION(76, 3, false),
ALTERNATE_FUNCTION(80, 3, false),
static const unsigned int southwest_spi3_altfuncs[] = {
PINMODE(3, 0), PINMODE(2, 0), PINMODE(3, 0), PINMODE(2, 0), /* 76, 79, 80, 81 */
PINMODE(2, 0), /* 82 */
};
static const struct chv_pingroup southwest_groups[] = {
PIN_GROUP_WITH_ALT("uart0_grp", southwest_uart0_pins, 2, false),
PIN_GROUP_WITH_ALT("uart1_grp", southwest_uart1_pins, 1, false),
PIN_GROUP_WITH_ALT("uart2_grp", southwest_uart2_pins, 1, false),
PIN_GROUP_WITH_ALT("hda_grp", southwest_hda_pins, 2, false),
PIN_GROUP_WITH_ALT("i2c0_grp", southwest_i2c0_pins, 1, true),
PIN_GROUP_WITH_ALT("i2c1_grp", southwest_i2c1_pins, 1, true),
PIN_GROUP_WITH_ALT("i2c2_grp", southwest_i2c2_pins, 1, true),
PIN_GROUP_WITH_ALT("i2c3_grp", southwest_i2c3_pins, 1, true),
PIN_GROUP_WITH_ALT("i2c4_grp", southwest_i2c4_pins, 1, true),
PIN_GROUP_WITH_ALT("i2c5_grp", southwest_i2c5_pins, 1, true),
PIN_GROUP_WITH_ALT("i2c6_grp", southwest_i2c6_pins, 1, true),
PIN_GROUP_WITH_ALT("i2c_nfc_grp", southwest_i2c_nfc_pins, 2, true),
PIN_GROUP_WITH_OVERRIDE("lpe_grp", southwest_lpe_pins, 1, false,
southwest_lpe_altfuncs),
PIN_GROUP_WITH_OVERRIDE("spi3_grp", southwest_spi3_pins, 2, false,
southwest_spi3_altfuncs),
static const struct intel_pingroup southwest_groups[] = {
PIN_GROUP("uart0_grp", southwest_uart0_pins, PINMODE(2, 0)),
PIN_GROUP("uart1_grp", southwest_uart1_pins, PINMODE(1, 0)),
PIN_GROUP("uart2_grp", southwest_uart2_pins, PINMODE(1, 0)),
PIN_GROUP("hda_grp", southwest_hda_pins, PINMODE(2, 0)),
PIN_GROUP("i2c0_grp", southwest_i2c0_pins, PINMODE(1, 1)),
PIN_GROUP("i2c1_grp", southwest_i2c1_pins, PINMODE(1, 1)),
PIN_GROUP("i2c2_grp", southwest_i2c2_pins, PINMODE(1, 1)),
PIN_GROUP("i2c3_grp", southwest_i2c3_pins, PINMODE(1, 1)),
PIN_GROUP("i2c4_grp", southwest_i2c4_pins, PINMODE(1, 1)),
PIN_GROUP("i2c5_grp", southwest_i2c5_pins, PINMODE(1, 1)),
PIN_GROUP("i2c6_grp", southwest_i2c6_pins, PINMODE(1, 1)),
PIN_GROUP("i2c_nfc_grp", southwest_i2c_nfc_pins, PINMODE(2, 1)),
PIN_GROUP("lpe_grp", southwest_lpe_pins, southwest_lpe_altfuncs),
PIN_GROUP("spi3_grp", southwest_spi3_pins, southwest_spi3_altfuncs),
};
static const char * const southwest_uart0_groups[] = { "uart0_grp" };
......@@ -360,14 +293,14 @@ static const struct intel_function southwest_functions[] = {
FUNCTION("spi3", southwest_spi3_groups),
};
static const struct chv_gpio_pinrange southwest_gpio_ranges[] = {
GPIO_PINRANGE(0, 7),
GPIO_PINRANGE(15, 22),
GPIO_PINRANGE(30, 37),
GPIO_PINRANGE(45, 52),
GPIO_PINRANGE(60, 67),
GPIO_PINRANGE(75, 82),
GPIO_PINRANGE(90, 97),
static const struct intel_padgroup southwest_gpps[] = {
CHV_GPP(0, 7),
CHV_GPP(15, 22),
CHV_GPP(30, 37),
CHV_GPP(45, 52),
CHV_GPP(60, 67),
CHV_GPP(75, 82),
CHV_GPP(90, 97),
};
static const struct chv_community southwest_community = {
......@@ -378,8 +311,8 @@ static const struct chv_community southwest_community = {
.ngroups = ARRAY_SIZE(southwest_groups),
.functions = southwest_functions,
.nfunctions = ARRAY_SIZE(southwest_functions),
.gpio_ranges = southwest_gpio_ranges,
.ngpio_ranges = ARRAY_SIZE(southwest_gpio_ranges),
.gpps = southwest_gpps,
.ngpps = ARRAY_SIZE(southwest_gpps),
/*
* Southwest community can generate GPIO interrupts only for the
* first 8 interrupts. The upper half (8-15) can only be used to
......@@ -455,20 +388,20 @@ static const struct pinctrl_pin_desc north_pins[] = {
PINCTRL_PIN(72, "PANEL0_VDDEN"),
};
static const struct chv_gpio_pinrange north_gpio_ranges[] = {
GPIO_PINRANGE(0, 8),
GPIO_PINRANGE(15, 27),
GPIO_PINRANGE(30, 41),
GPIO_PINRANGE(45, 56),
GPIO_PINRANGE(60, 72),
static const struct intel_padgroup north_gpps[] = {
CHV_GPP(0, 8),
CHV_GPP(15, 27),
CHV_GPP(30, 41),
CHV_GPP(45, 56),
CHV_GPP(60, 72),
};
static const struct chv_community north_community = {
.uid = "2",
.pins = north_pins,
.npins = ARRAY_SIZE(north_pins),
.gpio_ranges = north_gpio_ranges,
.ngpio_ranges = ARRAY_SIZE(north_gpio_ranges),
.gpps = north_gpps,
.ngpps = ARRAY_SIZE(north_gpps),
/*
* North community can generate GPIO interrupts only for the first
* 8 interrupts. The upper half (8-15) can only be used to trigger
......@@ -506,17 +439,17 @@ static const struct pinctrl_pin_desc east_pins[] = {
PINCTRL_PIN(26, "MF_ISH_I2C1_SDA"),
};
static const struct chv_gpio_pinrange east_gpio_ranges[] = {
GPIO_PINRANGE(0, 11),
GPIO_PINRANGE(15, 26),
static const struct intel_padgroup east_gpps[] = {
CHV_GPP(0, 11),
CHV_GPP(15, 26),
};
static const struct chv_community east_community = {
.uid = "3",
.pins = east_pins,
.npins = ARRAY_SIZE(east_pins),
.gpio_ranges = east_gpio_ranges,
.ngpio_ranges = ARRAY_SIZE(east_gpio_ranges),
.gpps = east_gpps,
.ngpps = ARRAY_SIZE(east_gpps),
.nirqs = 16,
.acpi_space_id = 0x93,
};
......@@ -596,14 +529,14 @@ static const unsigned southeast_sdmmc3_pins[] = {
static const unsigned southeast_spi1_pins[] = { 60, 61, 62, 64, 66 };
static const unsigned southeast_spi2_pins[] = { 2, 3, 4, 6, 7 };
static const struct chv_pingroup southeast_groups[] = {
PIN_GROUP_WITH_ALT("pwm0_grp", southeast_pwm0_pins, 1, false),
PIN_GROUP_WITH_ALT("pwm1_grp", southeast_pwm1_pins, 1, false),
PIN_GROUP_WITH_ALT("sdmmc1_grp", southeast_sdmmc1_pins, 1, false),
PIN_GROUP_WITH_ALT("sdmmc2_grp", southeast_sdmmc2_pins, 1, false),
PIN_GROUP_WITH_ALT("sdmmc3_grp", southeast_sdmmc3_pins, 1, false),
PIN_GROUP_WITH_ALT("spi1_grp", southeast_spi1_pins, 1, false),
PIN_GROUP_WITH_ALT("spi2_grp", southeast_spi2_pins, 4, false),
static const struct intel_pingroup southeast_groups[] = {
PIN_GROUP("pwm0_grp", southeast_pwm0_pins, PINMODE(1, 0)),
PIN_GROUP("pwm1_grp", southeast_pwm1_pins, PINMODE(1, 0)),
PIN_GROUP("sdmmc1_grp", southeast_sdmmc1_pins, PINMODE(1, 0)),
PIN_GROUP("sdmmc2_grp", southeast_sdmmc2_pins, PINMODE(1, 0)),
PIN_GROUP("sdmmc3_grp", southeast_sdmmc3_pins, PINMODE(1, 0)),
PIN_GROUP("spi1_grp", southeast_spi1_pins, PINMODE(1, 0)),
PIN_GROUP("spi2_grp", southeast_spi2_pins, PINMODE(4, 0)),
};
static const char * const southeast_pwm0_groups[] = { "pwm0_grp" };
......@@ -624,13 +557,13 @@ static const struct intel_function southeast_functions[] = {
FUNCTION("spi2", southeast_spi2_groups),
};
static const struct chv_gpio_pinrange southeast_gpio_ranges[] = {
GPIO_PINRANGE(0, 7),
GPIO_PINRANGE(15, 26),
GPIO_PINRANGE(30, 35),
GPIO_PINRANGE(45, 52),
GPIO_PINRANGE(60, 69),
GPIO_PINRANGE(75, 85),
static const struct intel_padgroup southeast_gpps[] = {
CHV_GPP(0, 7),
CHV_GPP(15, 26),
CHV_GPP(30, 35),
CHV_GPP(45, 52),
CHV_GPP(60, 69),
CHV_GPP(75, 85),
};
static const struct chv_community southeast_community = {
......@@ -641,8 +574,8 @@ static const struct chv_community southeast_community = {
.ngroups = ARRAY_SIZE(southeast_groups),
.functions = southeast_functions,
.nfunctions = ARRAY_SIZE(southeast_functions),
.gpio_ranges = southeast_gpio_ranges,
.ngpio_ranges = ARRAY_SIZE(southeast_gpio_ranges),
.gpps = southeast_gpps,
.ngpps = ARRAY_SIZE(southeast_gpps),
.nirqs = 16,
.acpi_space_id = 0x94,
};
......@@ -789,7 +722,7 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned int function, unsigned int group)
{
struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
const struct chv_pingroup *grp;
const struct intel_pingroup *grp;
unsigned long flags;
int i;
......@@ -808,22 +741,21 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev,
}
for (i = 0; i < grp->npins; i++) {
const struct chv_alternate_function *altfunc = &grp->altfunc;
int pin = grp->pins[i];
void __iomem *reg;
unsigned int mode;
bool invert_oe;
u32 value;
/* Check if there is pin-specific config */
if (grp->overrides) {
int j;
for (j = 0; j < grp->noverrides; j++) {
if (grp->overrides[j].pin == pin) {
altfunc = &grp->overrides[j];
break;
}
}
}
if (grp->modes)
mode = grp->modes[i];
else
mode = grp->mode;
/* Extract OE inversion */
invert_oe = mode & PINMODE_INVERT_OE;
mode &= ~PINMODE_INVERT_OE;
reg = chv_padreg(pctrl, pin, CHV_PADCTRL0);
value = readl(reg);
......@@ -831,18 +763,18 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev,
value &= ~CHV_PADCTRL0_GPIOEN;
/* Set to desired mode */
value &= ~CHV_PADCTRL0_PMODE_MASK;
value |= altfunc->mode << CHV_PADCTRL0_PMODE_SHIFT;
value |= mode << CHV_PADCTRL0_PMODE_SHIFT;
chv_writel(value, reg);
/* Update for invert_oe */
reg = chv_padreg(pctrl, pin, CHV_PADCTRL1);
value = readl(reg) & ~CHV_PADCTRL1_INVRXTX_MASK;
if (altfunc->invert_oe)
if (invert_oe)
value |= CHV_PADCTRL1_INVRXTX_TXENABLE;
chv_writel(value, reg);
dev_dbg(pctrl->dev, "configured pin %u mode %u OE %sinverted\n",
pin, altfunc->mode, altfunc->invert_oe ? "" : "not ");
pin, mode, invert_oe ? "" : "not ");
}
raw_spin_unlock_irqrestore(&chv_lock, flags);
......@@ -1594,14 +1526,14 @@ static int chv_gpio_add_pin_ranges(struct gpio_chip *chip)
{
struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
const struct chv_community *community = pctrl->community;
const struct chv_gpio_pinrange *range;
const struct intel_padgroup *gpp;
int ret, i;
for (i = 0; i < community->ngpio_ranges; i++) {
range = &community->gpio_ranges[i];
for (i = 0; i < community->ngpps; i++) {
gpp = &community->gpps[i];
ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev),
range->base, range->base,
range->npins);
gpp->base, gpp->base,
gpp->size);
if (ret) {
dev_err(pctrl->dev, "failed to add GPIO pin range\n");
return ret;
......@@ -1613,7 +1545,7 @@ static int chv_gpio_add_pin_ranges(struct gpio_chip *chip)
static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
{
const struct chv_gpio_pinrange *range;
const struct intel_padgroup *gpp;
struct gpio_chip *chip = &pctrl->chip;
bool need_valid_mask = !dmi_check_system(chv_no_valid_mask);
const struct chv_community *community = pctrl->community;
......@@ -1661,12 +1593,12 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
}
if (!need_valid_mask) {
for (i = 0; i < community->ngpio_ranges; i++) {
range = &community->gpio_ranges[i];
for (i = 0; i < community->ngpps; i++) {
gpp = &community->gpps[i];
irq_domain_associate_many(chip->irq.domain, irq_base,
range->base, range->npins);
irq_base += range->npins;
gpp->base, gpp->size);
irq_base += gpp->size;
}
}
......
......@@ -29,8 +29,6 @@
.gpio_base = (g), \
}
#define ICL_NO_GPIO -1
#define ICL_COMMUNITY(b, s, e, g) \
{ \
.barno = (b), \
......@@ -305,29 +303,29 @@ static const struct pinctrl_pin_desc icllp_pins[] = {
};
static const struct intel_padgroup icllp_community0_gpps[] = {
ICL_GPP(0, 0, 7, 0), /* GPP_G */
ICL_GPP(1, 8, 33, 32), /* GPP_B */
ICL_GPP(2, 34, 58, 64), /* GPP_A */
ICL_GPP(0, 0, 7, 0), /* GPP_G */
ICL_GPP(1, 8, 33, 32), /* GPP_B */
ICL_GPP(2, 34, 58, 64), /* GPP_A */
};
static const struct intel_padgroup icllp_community1_gpps[] = {
ICL_GPP(0, 59, 82, 96), /* GPP_H */
ICL_GPP(1, 83, 103, 128), /* GPP_D */
ICL_GPP(2, 104, 123, 160), /* GPP_F */
ICL_GPP(3, 124, 152, 192), /* vGPIO */
ICL_GPP(0, 59, 82, 96), /* GPP_H */
ICL_GPP(1, 83, 103, 128), /* GPP_D */
ICL_GPP(2, 104, 123, 160), /* GPP_F */
ICL_GPP(3, 124, 152, 192), /* vGPIO */
};
static const struct intel_padgroup icllp_community4_gpps[] = {
ICL_GPP(0, 153, 176, 224), /* GPP_C */
ICL_GPP(1, 177, 182, ICL_NO_GPIO), /* HVCMOS */
ICL_GPP(2, 183, 206, 256), /* GPP_E */
ICL_GPP(3, 207, 215, ICL_NO_GPIO), /* JTAG */
ICL_GPP(0, 153, 176, 224), /* GPP_C */
ICL_GPP(1, 177, 182, INTEL_GPIO_BASE_NOMAP), /* HVCMOS */
ICL_GPP(2, 183, 206, 256), /* GPP_E */
ICL_GPP(3, 207, 215, INTEL_GPIO_BASE_NOMAP), /* JTAG */
};
static const struct intel_padgroup icllp_community5_gpps[] = {
ICL_GPP(0, 216, 223, 288), /* GPP_R */
ICL_GPP(1, 224, 231, 320), /* GPP_S */
ICL_GPP(2, 232, 240, ICL_NO_GPIO), /* SPI */
ICL_GPP(0, 216, 223, 288), /* GPP_R */
ICL_GPP(1, 224, 231, 320), /* GPP_S */
ICL_GPP(2, 232, 240, INTEL_GPIO_BASE_NOMAP), /* SPI */
};
static const struct intel_community icllp_communities[] = {
......
......@@ -798,7 +798,7 @@ static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset,
for (j = 0; j < comm->ngpps; j++) {
const struct intel_padgroup *pgrp = &comm->gpps[j];
if (pgrp->gpio_base < 0)
if (pgrp->gpio_base == INTEL_GPIO_BASE_NOMAP)
continue;
if (offset >= pgrp->gpio_base &&
......@@ -1138,7 +1138,7 @@ static int intel_gpio_add_community_ranges(struct intel_pinctrl *pctrl,
for (i = 0; i < community->ngpps; i++) {
const struct intel_padgroup *gpp = &community->gpps[i];
if (gpp->gpio_base < 0)
if (gpp->gpio_base == INTEL_GPIO_BASE_NOMAP)
continue;
ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
......@@ -1180,7 +1180,7 @@ static unsigned int intel_gpio_ngpio(const struct intel_pinctrl *pctrl)
for (j = 0; j < community->ngpps; j++) {
const struct intel_padgroup *gpp = &community->gpps[j];
if (gpp->gpio_base < 0)
if (gpp->gpio_base == INTEL_GPIO_BASE_NOMAP)
continue;
if (gpp->gpio_base + gpp->size > ngpio)
......@@ -1276,8 +1276,18 @@ static int intel_pinctrl_add_padgroups(struct intel_pinctrl *pctrl,
if (gpps[i].size > 32)
return -EINVAL;
if (!gpps[i].gpio_base)
gpps[i].gpio_base = gpps[i].base;
/* Special treatment for GPIO base */
switch (gpps[i].gpio_base) {
case INTEL_GPIO_BASE_MATCH:
gpps[i].gpio_base = gpps[i].base;
break;
case INTEL_GPIO_BASE_ZERO:
gpps[i].gpio_base = 0;
break;
case INTEL_GPIO_BASE_NOMAP:
default:
break;
}
gpps[i].padown_num = padown_num;
......@@ -1596,7 +1606,7 @@ static void intel_restore_hostown(struct intel_pinctrl *pctrl, unsigned int c,
struct device *dev = pctrl->dev;
u32 requested;
if (padgrp->gpio_base < 0)
if (padgrp->gpio_base == INTEL_GPIO_BASE_NOMAP)
return;
requested = intel_gpio_is_requested(&pctrl->chip, padgrp->gpio_base, padgrp->size);
......
......@@ -53,8 +53,7 @@ struct intel_function {
* @reg_num: GPI_IS register number
* @base: Starting pin of this group
* @size: Size of this group (maximum is 32).
* @gpio_base: Starting GPIO base of this group (%0 if matches with @base,
* and %-1 if no GPIO mapping should be created)
* @gpio_base: Starting GPIO base of this group
* @padown_num: PAD_OWN register number (assigned by the core driver)
*
* If pad groups of a community are not the same size, use this structure
......@@ -68,6 +67,19 @@ struct intel_padgroup {
unsigned int padown_num;
};
/**
* enum - Special treatment for GPIO base in pad group
*
* @INTEL_GPIO_BASE_ZERO: force GPIO base to be 0
* @INTEL_GPIO_BASE_NOMAP: no GPIO mapping should be created
* @INTEL_GPIO_BASE_MATCH: matches with starting pin number
*/
enum {
INTEL_GPIO_BASE_ZERO = -2,
INTEL_GPIO_BASE_NOMAP = -1,
INTEL_GPIO_BASE_MATCH = 0,
};
/**
* struct intel_community - Intel pin community description
* @barno: MMIO BAR number where registers for this community reside
......@@ -82,20 +94,20 @@ struct intel_padgroup {
* @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
* @npins: Number 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.
* HOSTSW_OWN, GPI_IS, GPI_IE. Used when @gpps is %NULL.
* @gpp_num_padown_regs: Number of pad registers each pad group consumes at
* minimum. Use %0 if the number of registers can be
* determined by the size of the group.
* @npins: Number of pins in this community
* @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)
*
* Most Intel GPIO host controllers this driver supports each pad group is
* of equal size (except the last one). In that case the driver can just
* In some of Intel GPIO host controllers this driver supports each pad group
* is of equal size (except the last one). In that case the driver can just
* fill in @gpp_size field and let the core driver to handle the rest. If
* the controller has pad groups of variable size the client driver can
* pass custom @gpps and @ngpps instead.
......@@ -109,12 +121,13 @@ struct intel_community {
unsigned int ie_offset;
unsigned int features;
unsigned int pin_base;
size_t npins;
unsigned int gpp_size;
unsigned int gpp_num_padown_regs;
size_t npins;
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;
......
// SPDX-License-Identifier: GPL-2.0
/*
* Intel Jasper Lake PCH pinctrl/GPIO driver
*
* Copyright (C) 2020, Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*/
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-intel.h"
#define JSL_PAD_OWN 0x020
#define JSL_PADCFGLOCK 0x080
#define JSL_HOSTSW_OWN 0x0b0
#define JSL_GPI_IS 0x100
#define JSL_GPI_IE 0x120
#define JSL_GPP(r, s, e, g) \
{ \
.reg_num = (r), \
.base = (s), \
.size = ((e) - (s) + 1), \
.gpio_base = (g), \
}
#define JSL_COMMUNITY(b, s, e, g) \
{ \
.barno = (b), \
.padown_offset = JSL_PAD_OWN, \
.padcfglock_offset = JSL_PADCFGLOCK, \
.hostown_offset = JSL_HOSTSW_OWN, \
.is_offset = JSL_GPI_IS, \
.ie_offset = JSL_GPI_IE, \
.pin_base = (s), \
.npins = ((e) - (s) + 1), \
.gpps = (g), \
.ngpps = ARRAY_SIZE(g), \
}
/* Jasper Lake */
static const struct pinctrl_pin_desc jsl_pins[] = {
/* GPP_F */
PINCTRL_PIN(0, "CNV_BRI_DT_UART0_RTSB"),
PINCTRL_PIN(1, "CNV_BRI_RSP_UART0_RXD"),
PINCTRL_PIN(2, "EMMC_HIP_MON"),
PINCTRL_PIN(3, "CNV_RGI_RSP_UART0_CTSB"),
PINCTRL_PIN(4, "CNV_RF_RESET_B"),
PINCTRL_PIN(5, "MODEM_CLKREQ"),
PINCTRL_PIN(6, "CNV_PA_BLANKING"),
PINCTRL_PIN(7, "EMMC_CMD"),
PINCTRL_PIN(8, "EMMC_DATA0"),
PINCTRL_PIN(9, "EMMC_DATA1"),
PINCTRL_PIN(10, "EMMC_DATA2"),
PINCTRL_PIN(11, "EMMC_DATA3"),
PINCTRL_PIN(12, "EMMC_DATA4"),
PINCTRL_PIN(13, "EMMC_DATA5"),
PINCTRL_PIN(14, "EMMC_DATA6"),
PINCTRL_PIN(15, "EMMC_DATA7"),
PINCTRL_PIN(16, "EMMC_RCLK"),
PINCTRL_PIN(17, "EMMC_CLK"),
PINCTRL_PIN(18, "EMMC_RESETB"),
PINCTRL_PIN(19, "A4WP_PRESENT"),
/* GPP_B */
PINCTRL_PIN(20, "CORE_VID_0"),
PINCTRL_PIN(21, "CORE_VID_1"),
PINCTRL_PIN(22, "VRALERTB"),
PINCTRL_PIN(23, "CPU_GP_2"),
PINCTRL_PIN(24, "CPU_GP_3"),
PINCTRL_PIN(25, "SRCCLKREQB_0"),
PINCTRL_PIN(26, "SRCCLKREQB_1"),
PINCTRL_PIN(27, "SRCCLKREQB_2"),
PINCTRL_PIN(28, "SRCCLKREQB_3"),
PINCTRL_PIN(29, "SRCCLKREQB_4"),
PINCTRL_PIN(30, "SRCCLKREQB_5"),
PINCTRL_PIN(31, "PMCALERTB"),
PINCTRL_PIN(32, "SLP_S0B"),
PINCTRL_PIN(33, "PLTRSTB"),
PINCTRL_PIN(34, "SPKR"),
PINCTRL_PIN(35, "GSPI0_CS0B"),
PINCTRL_PIN(36, "GSPI0_CLK"),
PINCTRL_PIN(37, "GSPI0_MISO"),
PINCTRL_PIN(38, "GSPI0_MOSI"),
PINCTRL_PIN(39, "GSPI1_CS0B"),
PINCTRL_PIN(40, "GSPI1_CLK"),
PINCTRL_PIN(41, "GSPI1_MISO"),
PINCTRL_PIN(42, "GSPI1_MOSI"),
PINCTRL_PIN(43, "DDSP_HPD_A"),
PINCTRL_PIN(44, "GSPI0_CLK_LOOPBK"),
PINCTRL_PIN(45, "GSPI1_CLK_LOOPBK"),
/* GPP_A */
PINCTRL_PIN(46, "ESPI_IO_0"),
PINCTRL_PIN(47, "ESPI_IO_1"),
PINCTRL_PIN(48, "ESPI_IO_2"),
PINCTRL_PIN(49, "ESPI_IO_3"),
PINCTRL_PIN(50, "ESPI_CSB"),
PINCTRL_PIN(51, "ESPI_CLK"),
PINCTRL_PIN(52, "ESPI_RESETB"),
PINCTRL_PIN(53, "SMBCLK"),
PINCTRL_PIN(54, "SMBDATA"),
PINCTRL_PIN(55, "SMBALERTB"),
PINCTRL_PIN(56, "CPU_GP_0"),
PINCTRL_PIN(57, "CPU_GP_1"),
PINCTRL_PIN(58, "USB2_OCB_1"),
PINCTRL_PIN(59, "USB2_OCB_2"),
PINCTRL_PIN(60, "USB2_OCB_3"),
PINCTRL_PIN(61, "DDSP_HPD_A_TIME_SYNC_0"),
PINCTRL_PIN(62, "DDSP_HPD_B"),
PINCTRL_PIN(63, "DDSP_HPD_C"),
PINCTRL_PIN(64, "USB2_OCB_0"),
PINCTRL_PIN(65, "PCHHOTB"),
PINCTRL_PIN(66, "ESPI_CLK_LOOPBK"),
/* GPP_S */
PINCTRL_PIN(67, "SNDW1_CLK"),
PINCTRL_PIN(68, "SNDW1_DATA"),
PINCTRL_PIN(69, "SNDW2_CLK"),
PINCTRL_PIN(70, "SNDW2_DATA"),
PINCTRL_PIN(71, "SNDW1_CLK"),
PINCTRL_PIN(72, "SNDW1_DATA"),
PINCTRL_PIN(73, "SNDW4_CLK_DMIC_CLK_0"),
PINCTRL_PIN(74, "SNDW4_DATA_DMIC_DATA_0"),
/* GPP_R */
PINCTRL_PIN(75, "HDA_BCLK"),
PINCTRL_PIN(76, "HDA_SYNC"),
PINCTRL_PIN(77, "HDA_SDO"),
PINCTRL_PIN(78, "HDA_SDI_0"),
PINCTRL_PIN(79, "HDA_RSTB"),
PINCTRL_PIN(80, "HDA_SDI_1"),
PINCTRL_PIN(81, "I2S1_SFRM"),
PINCTRL_PIN(82, "I2S1_TXD"),
/* GPP_H */
PINCTRL_PIN(83, "GPPC_H_0"),
PINCTRL_PIN(84, "SD_PWR_EN_B"),
PINCTRL_PIN(85, "MODEM_CLKREQ"),
PINCTRL_PIN(86, "SX_EXIT_HOLDOFFB"),
PINCTRL_PIN(87, "I2C2_SDA"),
PINCTRL_PIN(88, "I2C2_SCL"),
PINCTRL_PIN(89, "I2C3_SDA"),
PINCTRL_PIN(90, "I2C3_SCL"),
PINCTRL_PIN(91, "I2C4_SDA"),
PINCTRL_PIN(92, "I2C4_SCL"),
PINCTRL_PIN(93, "CPU_VCCIO_PWR_GATEB"),
PINCTRL_PIN(94, "I2S2_SCLK"),
PINCTRL_PIN(95, "I2S2_SFRM"),
PINCTRL_PIN(96, "I2S2_TXD"),
PINCTRL_PIN(97, "I2S2_RXD"),
PINCTRL_PIN(98, "I2S1_SCLK"),
PINCTRL_PIN(99, "GPPC_H_16"),
PINCTRL_PIN(100, "GPPC_H_17"),
PINCTRL_PIN(101, "GPPC_H_18"),
PINCTRL_PIN(102, "GPPC_H_19"),
PINCTRL_PIN(103, "GPPC_H_20"),
PINCTRL_PIN(104, "GPPC_H_21"),
PINCTRL_PIN(105, "GPPC_H_22"),
PINCTRL_PIN(106, "GPPC_H_23"),
/* GPP_D */
PINCTRL_PIN(107, "SPI1_CSB"),
PINCTRL_PIN(108, "SPI1_CLK"),
PINCTRL_PIN(109, "SPI1_MISO_IO_1"),
PINCTRL_PIN(110, "SPI1_MOSI_IO_0"),
PINCTRL_PIN(111, "ISH_I2C0_SDA"),
PINCTRL_PIN(112, "ISH_I2C0_SCL"),
PINCTRL_PIN(113, "ISH_I2C1_SDA"),
PINCTRL_PIN(114, "ISH_I2C1_SCL"),
PINCTRL_PIN(115, "ISH_SPI_CSB"),
PINCTRL_PIN(116, "ISH_SPI_CLK"),
PINCTRL_PIN(117, "ISH_SPI_MISO"),
PINCTRL_PIN(118, "ISH_SPI_MOSI"),
PINCTRL_PIN(119, "ISH_UART0_RXD"),
PINCTRL_PIN(120, "ISH_UART0_TXD"),
PINCTRL_PIN(121, "ISH_UART0_RTSB"),
PINCTRL_PIN(122, "ISH_UART0_CTSB"),
PINCTRL_PIN(123, "SPI1_IO_2"),
PINCTRL_PIN(124, "SPI1_IO_3"),
PINCTRL_PIN(125, "I2S_MCLK"),
PINCTRL_PIN(126, "CNV_MFUART2_RXD"),
PINCTRL_PIN(127, "CNV_MFUART2_TXD"),
PINCTRL_PIN(128, "CNV_PA_BLANKING"),
PINCTRL_PIN(129, "I2C5_SDA"),
PINCTRL_PIN(130, "I2C5_SCL"),
PINCTRL_PIN(131, "GSPI2_CLK_LOOPBK"),
PINCTRL_PIN(132, "SPI1_CLK_LOOPBK"),
/* vGPIO */
PINCTRL_PIN(133, "CNV_BTEN"),
PINCTRL_PIN(134, "CNV_WCEN"),
PINCTRL_PIN(135, "CNV_BT_HOST_WAKEB"),
PINCTRL_PIN(136, "CNV_BT_IF_SELECT"),
PINCTRL_PIN(137, "vCNV_BT_UART_TXD"),
PINCTRL_PIN(138, "vCNV_BT_UART_RXD"),
PINCTRL_PIN(139, "vCNV_BT_UART_CTS_B"),
PINCTRL_PIN(140, "vCNV_BT_UART_RTS_B"),
PINCTRL_PIN(141, "vCNV_MFUART1_TXD"),
PINCTRL_PIN(142, "vCNV_MFUART1_RXD"),
PINCTRL_PIN(143, "vCNV_MFUART1_CTS_B"),
PINCTRL_PIN(144, "vCNV_MFUART1_RTS_B"),
PINCTRL_PIN(145, "vUART0_TXD"),
PINCTRL_PIN(146, "vUART0_RXD"),
PINCTRL_PIN(147, "vUART0_CTS_B"),
PINCTRL_PIN(148, "vUART0_RTS_B"),
PINCTRL_PIN(149, "vISH_UART0_TXD"),
PINCTRL_PIN(150, "vISH_UART0_RXD"),
PINCTRL_PIN(151, "vISH_UART0_CTS_B"),
PINCTRL_PIN(152, "vISH_UART0_RTS_B"),
PINCTRL_PIN(153, "vCNV_BT_I2S_BCLK"),
PINCTRL_PIN(154, "vCNV_BT_I2S_WS_SYNC"),
PINCTRL_PIN(155, "vCNV_BT_I2S_SDO"),
PINCTRL_PIN(156, "vCNV_BT_I2S_SDI"),
PINCTRL_PIN(157, "vI2S2_SCLK"),
PINCTRL_PIN(158, "vI2S2_SFRM"),
PINCTRL_PIN(159, "vI2S2_TXD"),
PINCTRL_PIN(160, "vI2S2_RXD"),
PINCTRL_PIN(161, "vSD3_CD_B"),
/* GPP_C */
PINCTRL_PIN(162, "GPPC_C_0"),
PINCTRL_PIN(163, "GPPC_C_1"),
PINCTRL_PIN(164, "GPPC_C_2"),
PINCTRL_PIN(165, "GPPC_C_3"),
PINCTRL_PIN(166, "GPPC_C_4"),
PINCTRL_PIN(167, "GPPC_C_5"),
PINCTRL_PIN(168, "SUSWARNB_SUSPWRDNACK"),
PINCTRL_PIN(169, "SUSACKB"),
PINCTRL_PIN(170, "UART0_RXD"),
PINCTRL_PIN(171, "UART0_TXD"),
PINCTRL_PIN(172, "UART0_RTSB"),
PINCTRL_PIN(173, "UART0_CTSB"),
PINCTRL_PIN(174, "UART1_RXD"),
PINCTRL_PIN(175, "UART1_TXD"),
PINCTRL_PIN(176, "UART1_RTSB"),
PINCTRL_PIN(177, "UART1_CTSB"),
PINCTRL_PIN(178, "I2C0_SDA"),
PINCTRL_PIN(179, "I2C0_SCL"),
PINCTRL_PIN(180, "I2C1_SDA"),
PINCTRL_PIN(181, "I2C1_SCL"),
PINCTRL_PIN(182, "UART2_RXD"),
PINCTRL_PIN(183, "UART2_TXD"),
PINCTRL_PIN(184, "UART2_RTSB"),
PINCTRL_PIN(185, "UART2_CTSB"),
/* HVCMOS */
PINCTRL_PIN(186, "L_BKLTEN"),
PINCTRL_PIN(187, "L_BKLTCTL"),
PINCTRL_PIN(188, "L_VDDEN"),
PINCTRL_PIN(189, "SYS_PWROK"),
PINCTRL_PIN(190, "SYS_RESETB"),
PINCTRL_PIN(191, "MLK_RSTB"),
/* GPP_E */
PINCTRL_PIN(192, "ISH_GP_0"),
PINCTRL_PIN(193, "ISH_GP_1"),
PINCTRL_PIN(194, "IMGCLKOUT_1"),
PINCTRL_PIN(195, "ISH_GP_2"),
PINCTRL_PIN(196, "IMGCLKOUT_2"),
PINCTRL_PIN(197, "SATA_LEDB"),
PINCTRL_PIN(198, "IMGCLKOUT_3"),
PINCTRL_PIN(199, "ISH_GP_3"),
PINCTRL_PIN(200, "ISH_GP_4"),
PINCTRL_PIN(201, "ISH_GP_5"),
PINCTRL_PIN(202, "ISH_GP_6"),
PINCTRL_PIN(203, "ISH_GP_7"),
PINCTRL_PIN(204, "IMGCLKOUT_4"),
PINCTRL_PIN(205, "DDPA_CTRLCLK"),
PINCTRL_PIN(206, "DDPA_CTRLDATA"),
PINCTRL_PIN(207, "DDPB_CTRLCLK"),
PINCTRL_PIN(208, "DDPB_CTRLDATA"),
PINCTRL_PIN(209, "DDPC_CTRLCLK"),
PINCTRL_PIN(210, "DDPC_CTRLDATA"),
PINCTRL_PIN(211, "IMGCLKOUT_5"),
PINCTRL_PIN(212, "CNV_BRI_DT"),
PINCTRL_PIN(213, "CNV_BRI_RSP"),
PINCTRL_PIN(214, "CNV_RGI_DT"),
PINCTRL_PIN(215, "CNV_RGI_RSP"),
/* GPP_G */
PINCTRL_PIN(216, "SD3_CMD"),
PINCTRL_PIN(217, "SD3_D0"),
PINCTRL_PIN(218, "SD3_D1"),
PINCTRL_PIN(219, "SD3_D2"),
PINCTRL_PIN(220, "SD3_D3"),
PINCTRL_PIN(221, "SD3_CDB"),
PINCTRL_PIN(222, "SD3_CLK"),
PINCTRL_PIN(223, "SD3_WP"),
};
static const struct intel_padgroup jsl_community0_gpps[] = {
JSL_GPP(0, 0, 19, 320), /* GPP_F */
JSL_GPP(1, 20, 45, 32), /* GPP_B */
JSL_GPP(2, 46, 66, 64), /* GPP_A */
JSL_GPP(3, 67, 74, 96), /* GPP_S */
JSL_GPP(4, 75, 82, 128), /* GPP_R */
};
static const struct intel_padgroup jsl_community1_gpps[] = {
JSL_GPP(0, 83, 106, 160), /* GPP_H */
JSL_GPP(1, 107, 132, 192), /* GPP_D */
JSL_GPP(2, 133, 161, 224), /* vGPIO */
JSL_GPP(3, 162, 185, 256), /* GPP_C */
};
static const struct intel_padgroup jsl_community4_gpps[] = {
JSL_GPP(0, 186, 191, INTEL_GPIO_BASE_NOMAP), /* HVCMOS */
JSL_GPP(1, 192, 215, 288), /* GPP_E */
};
static const struct intel_padgroup jsl_community5_gpps[] = {
JSL_GPP(0, 216, 223, INTEL_GPIO_BASE_ZERO), /* GPP_G */
};
static const struct intel_community jsl_communities[] = {
JSL_COMMUNITY(0, 0, 82, jsl_community0_gpps),
JSL_COMMUNITY(1, 83, 185, jsl_community1_gpps),
JSL_COMMUNITY(2, 186, 215, jsl_community4_gpps),
JSL_COMMUNITY(3, 216, 223, jsl_community5_gpps),
};
static const struct intel_pinctrl_soc_data jsl_soc_data = {
.pins = jsl_pins,
.npins = ARRAY_SIZE(jsl_pins),
.communities = jsl_communities,
.ncommunities = ARRAY_SIZE(jsl_communities),
};
static const struct acpi_device_id jsl_pinctrl_acpi_match[] = {
{ "INT34C8", (kernel_ulong_t)&jsl_soc_data },
{ }
};
MODULE_DEVICE_TABLE(acpi, jsl_pinctrl_acpi_match);
static INTEL_PINCTRL_PM_OPS(jsl_pinctrl_pm_ops);
static struct platform_driver jsl_pinctrl_driver = {
.probe = intel_pinctrl_probe_by_hid,
.driver = {
.name = "jasperlake-pinctrl",
.acpi_match_table = jsl_pinctrl_acpi_match,
.pm = &jsl_pinctrl_pm_ops,
},
};
module_platform_driver(jsl_pinctrl_driver);
MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
MODULE_DESCRIPTION("Intel Jasper Lake PCH pinctrl/GPIO driver");
MODULE_LICENSE("GPL v2");
......@@ -794,11 +794,11 @@ static int lp_gpio_probe(struct platform_device *pdev)
const struct intel_pinctrl_soc_data *soc;
struct intel_pinctrl *lg;
struct gpio_chip *gc;
struct resource *io_rc, *irq_rc;
struct device *dev = &pdev->dev;
struct resource *io_rc;
void __iomem *regs;
unsigned int i;
int ret;
int irq, ret;
soc = (const struct intel_pinctrl_soc_data *)device_get_match_data(dev);
if (!soc)
......@@ -870,8 +870,8 @@ static int lp_gpio_probe(struct platform_device *pdev)
gc->parent = dev;
/* set up interrupts */
irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (irq_rc && irq_rc->start) {
irq = platform_get_irq_optional(pdev, 0);
if (irq > 0) {
struct gpio_irq_chip *girq;
girq = &gc->irq;
......@@ -884,7 +884,7 @@ static int lp_gpio_probe(struct platform_device *pdev)
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
girq->parents[0] = (unsigned int)irq_rc->start;
girq->parents[0] = irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_bad_irq;
}
......
......@@ -21,8 +21,6 @@
#define TGL_GPI_IS 0x100
#define TGL_GPI_IE 0x120
#define TGL_NO_GPIO -1
#define TGL_GPP(r, s, e, g) \
{ \
.reg_num = (r), \
......@@ -342,30 +340,30 @@ static const struct pinctrl_pin_desc tgllp_pins[] = {
};
static const struct intel_padgroup tgllp_community0_gpps[] = {
TGL_GPP(0, 0, 25, 0), /* GPP_B */
TGL_GPP(1, 26, 41, 32), /* GPP_T */
TGL_GPP(2, 42, 66, 64), /* GPP_A */
TGL_GPP(0, 0, 25, 0), /* GPP_B */
TGL_GPP(1, 26, 41, 32), /* GPP_T */
TGL_GPP(2, 42, 66, 64), /* GPP_A */
};
static const struct intel_padgroup tgllp_community1_gpps[] = {
TGL_GPP(0, 67, 74, 96), /* GPP_S */
TGL_GPP(1, 75, 98, 128), /* GPP_H */
TGL_GPP(2, 99, 119, 160), /* GPP_D */
TGL_GPP(3, 120, 143, 192), /* GPP_U */
TGL_GPP(4, 144, 170, 224), /* vGPIO */
TGL_GPP(0, 67, 74, 96), /* GPP_S */
TGL_GPP(1, 75, 98, 128), /* GPP_H */
TGL_GPP(2, 99, 119, 160), /* GPP_D */
TGL_GPP(3, 120, 143, 192), /* GPP_U */
TGL_GPP(4, 144, 170, 224), /* vGPIO */
};
static const struct intel_padgroup tgllp_community4_gpps[] = {
TGL_GPP(0, 171, 194, 256), /* GPP_C */
TGL_GPP(1, 195, 219, 288), /* GPP_F */
TGL_GPP(2, 220, 225, TGL_NO_GPIO), /* HVCMOS */
TGL_GPP(3, 226, 250, 320), /* GPP_E */
TGL_GPP(4, 251, 259, TGL_NO_GPIO), /* JTAG */
TGL_GPP(0, 171, 194, 256), /* GPP_C */
TGL_GPP(1, 195, 219, 288), /* GPP_F */
TGL_GPP(2, 220, 225, INTEL_GPIO_BASE_NOMAP), /* HVCMOS */
TGL_GPP(3, 226, 250, 320), /* GPP_E */
TGL_GPP(4, 251, 259, INTEL_GPIO_BASE_NOMAP), /* JTAG */
};
static const struct intel_padgroup tgllp_community5_gpps[] = {
TGL_GPP(0, 260, 267, 352), /* GPP_R */
TGL_GPP(1, 268, 276, TGL_NO_GPIO), /* SPI */
TGL_GPP(0, 260, 267, 352), /* GPP_R */
TGL_GPP(1, 268, 276, INTEL_GPIO_BASE_NOMAP), /* SPI */
};
static const struct intel_community tgllp_communities[] = {
......
......@@ -3,10 +3,12 @@ menu "MediaTek pinctrl drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
config EINT_MTK
bool "MediaTek External Interrupt Support"
tristate "MediaTek External Interrupt Support"
depends on PINCTRL_MTK || PINCTRL_MTK_MOORE || PINCTRL_MTK_PARIS || COMPILE_TEST
select GPIOLIB
select IRQ_DOMAIN
default y if PINCTRL_MTK || PINCTRL_MTK_MOORE
default PINCTRL_MTK_PARIS
config PINCTRL_MTK
bool
......@@ -17,6 +19,9 @@ config PINCTRL_MTK
select EINT_MTK
select OF_GPIO
config PINCTRL_MTK_V2
tristate
config PINCTRL_MTK_MOORE
bool
depends on OF
......@@ -25,15 +30,17 @@ config PINCTRL_MTK_MOORE
select GENERIC_PINMUX_FUNCTIONS
select GPIOLIB
select OF_GPIO
select PINCTRL_MTK_V2
config PINCTRL_MTK_PARIS
bool
tristate
depends on OF
select PINMUX
select GENERIC_PINCONF
select GPIOLIB
select EINT_MTK
select OF_GPIO
select PINCTRL_MTK_V2
# For ARMv7 SoCs
config PINCTRL_MT2701
......@@ -80,7 +87,7 @@ config PINCTRL_MT2712
select PINCTRL_MTK
config PINCTRL_MT6765
bool "Mediatek MT6765 pin control"
tristate "Mediatek MT6765 pin control"
depends on OF
depends on ARM64 || COMPILE_TEST
default ARM64 && ARCH_MEDIATEK
......
......@@ -2,8 +2,9 @@
# Core
obj-$(CONFIG_EINT_MTK) += mtk-eint.o
obj-$(CONFIG_PINCTRL_MTK) += pinctrl-mtk-common.o
obj-$(CONFIG_PINCTRL_MTK_MOORE) += pinctrl-moore.o pinctrl-mtk-common-v2.o
obj-$(CONFIG_PINCTRL_MTK_PARIS) += pinctrl-paris.o pinctrl-mtk-common-v2.o
obj-$(CONFIG_PINCTRL_MTK_V2) += pinctrl-mtk-common-v2.o
obj-$(CONFIG_PINCTRL_MTK_MOORE) += pinctrl-moore.o
obj-$(CONFIG_PINCTRL_MTK_PARIS) += pinctrl-paris.o
# SoC Drivers
obj-$(CONFIG_PINCTRL_MT2701) += pinctrl-mt2701.o
......
......@@ -15,6 +15,7 @@
#include <linux/io.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/module.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
......@@ -379,6 +380,7 @@ int mtk_eint_do_suspend(struct mtk_eint *eint)
return 0;
}
EXPORT_SYMBOL_GPL(mtk_eint_do_suspend);
int mtk_eint_do_resume(struct mtk_eint *eint)
{
......@@ -386,6 +388,7 @@ int mtk_eint_do_resume(struct mtk_eint *eint)
return 0;
}
EXPORT_SYMBOL_GPL(mtk_eint_do_resume);
int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
unsigned int debounce)
......@@ -440,6 +443,7 @@ int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_eint_set_debounce);
int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
{
......@@ -451,6 +455,7 @@ int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
return irq;
}
EXPORT_SYMBOL_GPL(mtk_eint_find_irq);
int mtk_eint_do_init(struct mtk_eint *eint)
{
......@@ -495,3 +500,7 @@ int mtk_eint_do_init(struct mtk_eint *eint)
return 0;
}
EXPORT_SYMBOL_GPL(mtk_eint_do_init);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MediaTek EINT Driver");
......@@ -6,6 +6,7 @@
*
*/
#include <linux/module.h>
#include "pinctrl-mtk-mt6765.h"
#include "pinctrl-paris.h"
......@@ -1103,3 +1104,6 @@ static int __init mt6765_pinctrl_init(void)
return platform_driver_register(&mt6765_pinctrl_driver);
}
arch_initcall(mt6765_pinctrl_init);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MediaTek MT6765 Pinctrl Driver");
......@@ -12,6 +12,7 @@
#include <linux/gpio/driver.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_irq.h>
#include "mtk-eint.h"
......@@ -204,6 +205,7 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_hw_set_value);
int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
int field, int *value)
......@@ -223,6 +225,7 @@ int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_hw_get_value);
static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
{
......@@ -361,6 +364,7 @@ int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
return mtk_eint_do_init(hw->eint);
}
EXPORT_SYMBOL_GPL(mtk_build_eint);
/* Revision 0 */
int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw,
......@@ -380,6 +384,7 @@ int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set);
int mtk_pinconf_bias_disable_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *res)
......@@ -402,6 +407,7 @@ int mtk_pinconf_bias_disable_get(struct mtk_pinctrl *hw,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get);
int mtk_pinconf_bias_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup)
......@@ -421,6 +427,7 @@ int mtk_pinconf_bias_set(struct mtk_pinctrl *hw,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set);
int mtk_pinconf_bias_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup, int *res)
......@@ -440,6 +447,7 @@ int mtk_pinconf_bias_get(struct mtk_pinctrl *hw,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get);
/* Revision 1 */
int mtk_pinconf_bias_disable_set_rev1(struct mtk_pinctrl *hw,
......@@ -454,6 +462,7 @@ int mtk_pinconf_bias_disable_set_rev1(struct mtk_pinctrl *hw,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_set_rev1);
int mtk_pinconf_bias_disable_get_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *res)
......@@ -471,6 +480,7 @@ int mtk_pinconf_bias_disable_get_rev1(struct mtk_pinctrl *hw,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_bias_disable_get_rev1);
int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup)
......@@ -490,6 +500,7 @@ int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_rev1);
int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
......@@ -515,6 +526,7 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_rev1);
/* Combo for the following pull register type:
* 1. PU + PD
......@@ -715,6 +727,7 @@ int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
out:
return err;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_combo);
int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
......@@ -735,6 +748,7 @@ int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
out:
return err;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_combo);
/* Revision 0 */
int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
......@@ -764,6 +778,7 @@ int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
return err;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set);
int mtk_pinconf_drive_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *val)
......@@ -788,6 +803,7 @@ int mtk_pinconf_drive_get(struct mtk_pinctrl *hw,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get);
/* Revision 1 */
int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
......@@ -809,6 +825,7 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
return err;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_rev1);
int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *val)
......@@ -826,18 +843,21 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_rev1);
int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg)
{
return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
}
EXPORT_SYMBOL_GPL(mtk_pinconf_drive_set_raw);
int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *val)
{
return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
}
EXPORT_SYMBOL_GPL(mtk_pinconf_drive_get_raw);
int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
......@@ -878,6 +898,7 @@ int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
return err;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_set);
int mtk_pinconf_adv_pull_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
......@@ -920,6 +941,7 @@ int mtk_pinconf_adv_pull_get(struct mtk_pinctrl *hw,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_adv_pull_get);
int mtk_pinconf_adv_drive_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg)
......@@ -946,6 +968,7 @@ int mtk_pinconf_adv_drive_set(struct mtk_pinctrl *hw,
return err;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_set);
int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 *val)
......@@ -969,3 +992,8 @@ int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_pinconf_adv_drive_get);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
MODULE_DESCRIPTION("Pin configuration library module for mediatek SoCs");
......@@ -10,6 +10,7 @@
*/
#include <linux/gpio/driver.h>
#include <linux/module.h>
#include <dt-bindings/pinctrl/mt65xx.h>
#include "pinctrl-paris.h"
......@@ -631,6 +632,7 @@ ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
return len;
}
EXPORT_SYMBOL_GPL(mtk_pctrl_show_one_pin);
#define PIN_DBG_BUF_SZ 96
static void mtk_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
......@@ -1019,6 +1021,7 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev,
return 0;
}
EXPORT_SYMBOL_GPL(mtk_paris_pinctrl_probe);
static int mtk_paris_pinctrl_suspend(struct device *device)
{
......@@ -1038,3 +1041,6 @@ const struct dev_pm_ops mtk_paris_pinctrl_pm_ops = {
.suspend_noirq = mtk_paris_pinctrl_suspend,
.resume_noirq = mtk_paris_pinctrl_resume,
};
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MediaTek Pinctrl Common Driver V2 Paris");
......@@ -549,6 +549,18 @@ static const struct pinconf_ops meson_pinconf_ops = {
.is_generic = true,
};
static int meson_gpio_get_direction(struct gpio_chip *chip, unsigned gpio)
{
struct meson_pinctrl *pc = gpiochip_get_data(chip);
int ret;
ret = meson_pinconf_get_output(pc, gpio);
if (ret < 0)
return ret;
return ret ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
}
static int meson_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
{
return meson_pinconf_set_output(gpiochip_get_data(chip), gpio, false);
......@@ -591,6 +603,8 @@ static int meson_gpiolib_register(struct meson_pinctrl *pc)
pc->chip.parent = pc->dev;
pc->chip.request = gpiochip_generic_request;
pc->chip.free = gpiochip_generic_free;
pc->chip.set_config = gpiochip_generic_config;
pc->chip.get_direction = meson_gpio_get_direction;
pc->chip.direction_input = meson_gpio_direction_input;
pc->chip.direction_output = meson_gpio_direction_output;
pc->chip.get = meson_gpio_get;
......
......@@ -178,6 +178,7 @@ static const struct abx500_pingroup ab8505_groups[] = {
AB8505_PIN_GROUP(gpio40_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio41_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(uartrxdata_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio50_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio52_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(gpio53_a_1, ABX500_ALT_A),
AB8505_PIN_GROUP(pdmdata_b_1, ABX500_ALT_B),
......
......@@ -691,18 +691,21 @@ static const struct nmk_pingroup nmk_db8500_groups[] = {
DB8500_PIN_GROUP(lcd_d8_d11_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(lcd_d12_d23_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(kp_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(kpskaskb_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(mc2_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(ssp1_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(ssp0_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(ipgpio0_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(ipgpio1_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(modem_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(kp_a_2, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(msp2sck_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(msp2_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(mc4_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(mc1_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(mc1_a_2, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(mc1dir_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A),
DB8500_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A),
......@@ -760,7 +763,7 @@ static const struct nmk_pingroup nmk_db8500_groups[] = {
DB8500_PIN_GROUP(u0_c_1, NMK_GPIO_ALT_C),
DB8500_PIN_GROUP(ipgpio4_c_1, NMK_GPIO_ALT_C),
DB8500_PIN_GROUP(ipgpio5_c_1, NMK_GPIO_ALT_C),
DB8500_PIN_GROUP(ipgpio6_c_1, NMK_GPIO_ALT_C),
DB8500_PIN_GROUP(ipgpio6_c_2, NMK_GPIO_ALT_C),
DB8500_PIN_GROUP(ipgpio7_c_1, NMK_GPIO_ALT_C),
DB8500_PIN_GROUP(smcleale_c_1, NMK_GPIO_ALT_C),
DB8500_PIN_GROUP(stmape_c_1, NMK_GPIO_ALT_C),
......@@ -955,6 +958,7 @@ static const struct nmk_function nmk_db8500_functions[] = {
FUNCTION(spi0),
FUNCTION(spi2),
FUNCTION(remap),
FUNCTION(sbag),
FUNCTION(ptm),
FUNCTION(rf),
FUNCTION(hx),
......
......@@ -1343,8 +1343,6 @@ static const struct nmk_cfg_param nmk_cfg_params[] = {
static int nmk_dt_pin_config(int index, int val, unsigned long *config)
{
int ret = 0;
if (nmk_cfg_params[index].choice == NULL)
*config = nmk_cfg_params[index].config;
else {
......@@ -1354,7 +1352,7 @@ static int nmk_dt_pin_config(int index, int val, unsigned long *config)
nmk_cfg_params[index].choice[val];
}
}
return ret;
return 0;
}
static const char *nmk_find_pin_name(struct pinctrl_dev *pctldev, const char *pin_name)
......
......@@ -1019,7 +1019,7 @@ static int atmel_pinctrl_probe(struct platform_device *pdev)
atmel_pioctrl->reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(atmel_pioctrl->reg_base))
return -EINVAL;
return PTR_ERR(atmel_pioctrl->reg_base);
atmel_pioctrl->clk = devm_clk_get(dev, NULL);
if (IS_ERR(atmel_pioctrl->clk)) {
......
......@@ -408,6 +408,7 @@ static const struct bm1880_pctrl_group bm1880_pctrl_groups[] = {
BM1880_PINCTRL_GRP(pwm34),
BM1880_PINCTRL_GRP(pwm35),
BM1880_PINCTRL_GRP(pwm36),
BM1880_PINCTRL_GRP(pwm37),
BM1880_PINCTRL_GRP(i2c0),
BM1880_PINCTRL_GRP(i2c1),
BM1880_PINCTRL_GRP(i2c2),
......
......@@ -1977,6 +1977,25 @@ static const struct pinctrl_ops ingenic_pctlops = {
.dt_free_map = pinconf_generic_dt_free_map,
};
static int ingenic_gpio_irq_request(struct irq_data *data)
{
struct gpio_chip *gpio_chip = irq_data_get_irq_chip_data(data);
int ret;
ret = ingenic_gpio_direction_input(gpio_chip, data->hwirq);
if (ret)
return ret;
return gpiochip_reqres_irq(gpio_chip, data->hwirq);
}
static void ingenic_gpio_irq_release(struct irq_data *data)
{
struct gpio_chip *gpio_chip = irq_data_get_irq_chip_data(data);
return gpiochip_relres_irq(gpio_chip, data->hwirq);
}
static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc,
int pin, int func)
{
......@@ -2338,6 +2357,8 @@ static int __init ingenic_gpio_probe(struct ingenic_pinctrl *jzpc,
jzgc->irq_chip.irq_ack = ingenic_gpio_irq_ack;
jzgc->irq_chip.irq_set_type = ingenic_gpio_irq_set_type;
jzgc->irq_chip.irq_set_wake = ingenic_gpio_irq_set_wake;
jzgc->irq_chip.irq_request_resources = ingenic_gpio_irq_request;
jzgc->irq_chip.irq_release_resources = ingenic_gpio_irq_release;
jzgc->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND;
girq = &jzgc->gc.irq;
......
......@@ -221,7 +221,7 @@ static int match_mux(const struct ltq_mfp_pin *mfp, unsigned mux)
return i;
}
/* dont assume .mfp is linearly mapped. find the mfp with the correct .pin */
/* don't assume .mfp is linearly mapped. find the mfp with the correct .pin */
static int match_mfp(const struct ltq_pinmux_info *info, int pin)
{
int i;
......
// SPDX-License-Identifier: GPL-2.0-only
/* MCP23S08 SPI/I2C GPIO driver */
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/export.h>
#include <linux/gpio/driver.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <linux/spi/mcp23s08.h>
#include <linux/slab.h>
#include <asm/byteorder.h>
#include <linux/interrupt.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
/*
* MCP types supported by driver
*/
#define MCP_TYPE_S08 0
#define MCP_TYPE_S17 1
#define MCP_TYPE_008 2
#define MCP_TYPE_017 3
#define MCP_TYPE_S18 4
#define MCP_TYPE_018 5
#define MCP_MAX_DEV_PER_CS 8
#include "pinctrl-mcp23s08.h"
/* Registers are all 8 bits wide.
*
......@@ -53,31 +42,6 @@
#define MCP_GPIO 0x09
#define MCP_OLAT 0x0a
struct mcp23s08;
struct mcp23s08 {
u8 addr;
bool irq_active_high;
bool reg_shift;
u16 irq_rise;
u16 irq_fall;
int irq;
bool irq_controller;
int cached_gpio;
/* lock protects regmap access with bypass/cache flags */
struct mutex lock;
struct gpio_chip chip;
struct irq_chip irq_chip;
struct regmap *regmap;
struct device *dev;
struct pinctrl_dev *pctldev;
struct pinctrl_desc pinctrl_desc;
};
static const struct reg_default mcp23x08_defaults[] = {
{.reg = MCP_IODIR, .def = 0xff},
{.reg = MCP_IPOL, .def = 0x00},
......@@ -109,7 +73,7 @@ static const struct regmap_access_table mcp23x08_precious_table = {
.n_yes_ranges = 1,
};
static const struct regmap_config mcp23x08_regmap = {
const struct regmap_config mcp23x08_regmap = {
.reg_bits = 8,
.val_bits = 8,
......@@ -121,6 +85,7 @@ static const struct regmap_config mcp23x08_regmap = {
.cache_type = REGCACHE_FLAT,
.max_register = MCP_OLAT,
};
EXPORT_SYMBOL_GPL(mcp23x08_regmap);
static const struct reg_default mcp23x16_defaults[] = {
{.reg = MCP_IODIR << 1, .def = 0xffff},
......@@ -153,7 +118,7 @@ static const struct regmap_access_table mcp23x16_precious_table = {
.n_yes_ranges = 1,
};
static const struct regmap_config mcp23x17_regmap = {
const struct regmap_config mcp23x17_regmap = {
.reg_bits = 8,
.val_bits = 16,
......@@ -166,6 +131,7 @@ static const struct regmap_config mcp23x17_regmap = {
.cache_type = REGCACHE_FLAT,
.val_format_endian = REGMAP_ENDIAN_LITTLE,
};
EXPORT_SYMBOL_GPL(mcp23x17_regmap);
static int mcp_read(struct mcp23s08 *mcp, unsigned int reg, unsigned int *val)
{
......@@ -309,80 +275,6 @@ static const struct pinconf_ops mcp_pinconf_ops = {
/*----------------------------------------------------------------------*/
#ifdef CONFIG_SPI_MASTER
static int mcp23sxx_spi_write(void *context, const void *data, size_t count)
{
struct mcp23s08 *mcp = context;
struct spi_device *spi = to_spi_device(mcp->dev);
struct spi_message m;
struct spi_transfer t[2] = { { .tx_buf = &mcp->addr, .len = 1, },
{ .tx_buf = data, .len = count, }, };
spi_message_init(&m);
spi_message_add_tail(&t[0], &m);
spi_message_add_tail(&t[1], &m);
return spi_sync(spi, &m);
}
static int mcp23sxx_spi_gather_write(void *context,
const void *reg, size_t reg_size,
const void *val, size_t val_size)
{
struct mcp23s08 *mcp = context;
struct spi_device *spi = to_spi_device(mcp->dev);
struct spi_message m;
struct spi_transfer t[3] = { { .tx_buf = &mcp->addr, .len = 1, },
{ .tx_buf = reg, .len = reg_size, },
{ .tx_buf = val, .len = val_size, }, };
spi_message_init(&m);
spi_message_add_tail(&t[0], &m);
spi_message_add_tail(&t[1], &m);
spi_message_add_tail(&t[2], &m);
return spi_sync(spi, &m);
}
static int mcp23sxx_spi_read(void *context, const void *reg, size_t reg_size,
void *val, size_t val_size)
{
struct mcp23s08 *mcp = context;
struct spi_device *spi = to_spi_device(mcp->dev);
u8 tx[2];
if (reg_size != 1)
return -EINVAL;
tx[0] = mcp->addr | 0x01;
tx[1] = *((u8 *) reg);
return spi_write_then_read(spi, tx, sizeof(tx), val, val_size);
}
static const struct regmap_bus mcp23sxx_spi_regmap = {
.write = mcp23sxx_spi_write,
.gather_write = mcp23sxx_spi_gather_write,
.read = mcp23sxx_spi_read,
};
#endif /* CONFIG_SPI_MASTER */
/*----------------------------------------------------------------------*/
/* A given spi_device can represent up to eight mcp23sxx chips
* sharing the same chipselect but using different addresses
* (e.g. chips #0 and #3 might be populated, but not #1 or $2).
* Driver data holds all the per-chip data.
*/
struct mcp23s08_driver_data {
unsigned ngpio;
struct mcp23s08 *mcp[8];
struct mcp23s08 chip[];
};
static int mcp23s08_direction_input(struct gpio_chip *chip, unsigned offset)
{
struct mcp23s08 *mcp = gpiochip_get_data(chip);
......@@ -562,7 +454,6 @@ static int mcp23s08_irq_set_type(struct irq_data *data, unsigned int type)
struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
struct mcp23s08 *mcp = gpiochip_get_data(gc);
unsigned int pos = data->hwirq;
int status = 0;
if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
mcp_set_bit(mcp, MCP_INTCON, pos, false);
......@@ -585,7 +476,7 @@ static int mcp23s08_irq_set_type(struct irq_data *data, unsigned int type)
} else
return -EINVAL;
return status;
return 0;
}
static void mcp23s08_irq_bus_lock(struct irq_data *data)
......@@ -656,21 +547,25 @@ static int mcp23s08_irqchip_setup(struct mcp23s08 *mcp)
/*----------------------------------------------------------------------*/
static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
void *data, unsigned addr, unsigned type,
unsigned int base, int cs)
int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
unsigned int addr, unsigned int type, unsigned int base)
{
int status, ret;
bool mirror = false;
bool open_drain = false;
struct regmap_config *one_regmap_config = NULL;
int raw_chip_address = (addr & ~0x40) >> 1;
mutex_init(&mcp->lock);
mcp->dev = dev;
mcp->addr = addr;
mcp->irq_active_high = false;
mcp->irq_chip.name = dev_name(dev);
mcp->irq_chip.irq_mask = mcp23s08_irq_mask;
mcp->irq_chip.irq_unmask = mcp23s08_irq_unmask;
mcp->irq_chip.irq_set_type = mcp23s08_irq_set_type;
mcp->irq_chip.irq_bus_lock = mcp23s08_irq_bus_lock;
mcp->irq_chip.irq_bus_sync_unlock = mcp23s08_irq_bus_unlock;
mcp->chip.direction_input = mcp23s08_direction_input;
mcp->chip.get = mcp23s08_get;
......@@ -681,83 +576,6 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
mcp->chip.of_node = dev->of_node;
#endif
switch (type) {
#ifdef CONFIG_SPI_MASTER
case MCP_TYPE_S08:
case MCP_TYPE_S17:
switch (type) {
case MCP_TYPE_S08:
one_regmap_config =
devm_kmemdup(dev, &mcp23x08_regmap,
sizeof(struct regmap_config), GFP_KERNEL);
mcp->reg_shift = 0;
mcp->chip.ngpio = 8;
mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL,
"mcp23s08.%d", raw_chip_address);
break;
case MCP_TYPE_S17:
one_regmap_config =
devm_kmemdup(dev, &mcp23x17_regmap,
sizeof(struct regmap_config), GFP_KERNEL);
mcp->reg_shift = 1;
mcp->chip.ngpio = 16;
mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL,
"mcp23s17.%d", raw_chip_address);
break;
}
if (!one_regmap_config)
return -ENOMEM;
one_regmap_config->name = devm_kasprintf(dev, GFP_KERNEL, "%d", raw_chip_address);
mcp->regmap = devm_regmap_init(dev, &mcp23sxx_spi_regmap, mcp,
one_regmap_config);
break;
case MCP_TYPE_S18:
one_regmap_config =
devm_kmemdup(dev, &mcp23x17_regmap,
sizeof(struct regmap_config), GFP_KERNEL);
if (!one_regmap_config)
return -ENOMEM;
mcp->regmap = devm_regmap_init(dev, &mcp23sxx_spi_regmap, mcp,
one_regmap_config);
mcp->reg_shift = 1;
mcp->chip.ngpio = 16;
mcp->chip.label = "mcp23s18";
break;
#endif /* CONFIG_SPI_MASTER */
#if IS_ENABLED(CONFIG_I2C)
case MCP_TYPE_008:
mcp->regmap = devm_regmap_init_i2c(data, &mcp23x08_regmap);
mcp->reg_shift = 0;
mcp->chip.ngpio = 8;
mcp->chip.label = "mcp23008";
break;
case MCP_TYPE_017:
mcp->regmap = devm_regmap_init_i2c(data, &mcp23x17_regmap);
mcp->reg_shift = 1;
mcp->chip.ngpio = 16;
mcp->chip.label = "mcp23017";
break;
case MCP_TYPE_018:
mcp->regmap = devm_regmap_init_i2c(data, &mcp23x17_regmap);
mcp->reg_shift = 1;
mcp->chip.ngpio = 16;
mcp->chip.label = "mcp23018";
break;
#endif /* CONFIG_I2C */
default:
dev_err(dev, "invalid device type (%d)\n", type);
return -EINVAL;
}
if (IS_ERR(mcp->regmap))
return PTR_ERR(mcp->regmap);
mcp->chip.base = base;
mcp->chip.can_sleep = true;
mcp->chip.parent = dev;
......@@ -816,14 +634,6 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
goto fail;
}
if (one_regmap_config) {
mcp->pinctrl_desc.name = devm_kasprintf(dev, GFP_KERNEL,
"mcp23xxx-pinctrl.%d", raw_chip_address);
if (!mcp->pinctrl_desc.name)
return -ENOMEM;
} else {
mcp->pinctrl_desc.name = "mcp23xxx-pinctrl";
}
mcp->pinctrl_desc.pctlops = &mcp_pinctrl_ops;
mcp->pinctrl_desc.confops = &mcp_pinconf_ops;
mcp->pinctrl_desc.npins = mcp->chip.ngpio;
......@@ -847,291 +657,5 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
dev_dbg(dev, "can't setup chip %d, --> %d\n", addr, ret);
return ret;
}
/*----------------------------------------------------------------------*/
#ifdef CONFIG_OF
#ifdef CONFIG_SPI_MASTER
static const struct of_device_id mcp23s08_spi_of_match[] = {
{
.compatible = "microchip,mcp23s08",
.data = (void *) MCP_TYPE_S08,
},
{
.compatible = "microchip,mcp23s17",
.data = (void *) MCP_TYPE_S17,
},
{
.compatible = "microchip,mcp23s18",
.data = (void *) MCP_TYPE_S18,
},
/* NOTE: The use of the mcp prefix is deprecated and will be removed. */
{
.compatible = "mcp,mcp23s08",
.data = (void *) MCP_TYPE_S08,
},
{
.compatible = "mcp,mcp23s17",
.data = (void *) MCP_TYPE_S17,
},
{ },
};
MODULE_DEVICE_TABLE(of, mcp23s08_spi_of_match);
#endif
#if IS_ENABLED(CONFIG_I2C)
static const struct of_device_id mcp23s08_i2c_of_match[] = {
{
.compatible = "microchip,mcp23008",
.data = (void *) MCP_TYPE_008,
},
{
.compatible = "microchip,mcp23017",
.data = (void *) MCP_TYPE_017,
},
{
.compatible = "microchip,mcp23018",
.data = (void *) MCP_TYPE_018,
},
/* NOTE: The use of the mcp prefix is deprecated and will be removed. */
{
.compatible = "mcp,mcp23008",
.data = (void *) MCP_TYPE_008,
},
{
.compatible = "mcp,mcp23017",
.data = (void *) MCP_TYPE_017,
},
{ },
};
MODULE_DEVICE_TABLE(of, mcp23s08_i2c_of_match);
#endif
#endif /* CONFIG_OF */
#if IS_ENABLED(CONFIG_I2C)
static int mcp230xx_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct mcp23s08_platform_data *pdata, local_pdata;
struct mcp23s08 *mcp;
int status;
pdata = dev_get_platdata(&client->dev);
if (!pdata) {
pdata = &local_pdata;
pdata->base = -1;
}
mcp = devm_kzalloc(&client->dev, sizeof(*mcp), GFP_KERNEL);
if (!mcp)
return -ENOMEM;
mcp->irq = client->irq;
mcp->irq_chip.name = dev_name(&client->dev);
mcp->irq_chip.irq_mask = mcp23s08_irq_mask;
mcp->irq_chip.irq_unmask = mcp23s08_irq_unmask;
mcp->irq_chip.irq_set_type = mcp23s08_irq_set_type;
mcp->irq_chip.irq_bus_lock = mcp23s08_irq_bus_lock;
mcp->irq_chip.irq_bus_sync_unlock = mcp23s08_irq_bus_unlock;
status = mcp23s08_probe_one(mcp, &client->dev, client, client->addr,
id->driver_data, pdata->base, 0);
if (status)
return status;
i2c_set_clientdata(client, mcp);
return 0;
}
static const struct i2c_device_id mcp230xx_id[] = {
{ "mcp23008", MCP_TYPE_008 },
{ "mcp23017", MCP_TYPE_017 },
{ "mcp23018", MCP_TYPE_018 },
{ },
};
MODULE_DEVICE_TABLE(i2c, mcp230xx_id);
static struct i2c_driver mcp230xx_driver = {
.driver = {
.name = "mcp230xx",
.of_match_table = of_match_ptr(mcp23s08_i2c_of_match),
},
.probe = mcp230xx_probe,
.id_table = mcp230xx_id,
};
static int __init mcp23s08_i2c_init(void)
{
return i2c_add_driver(&mcp230xx_driver);
}
static void mcp23s08_i2c_exit(void)
{
i2c_del_driver(&mcp230xx_driver);
}
#else
static int __init mcp23s08_i2c_init(void) { return 0; }
static void mcp23s08_i2c_exit(void) { }
#endif /* CONFIG_I2C */
/*----------------------------------------------------------------------*/
#ifdef CONFIG_SPI_MASTER
static int mcp23s08_probe(struct spi_device *spi)
{
struct mcp23s08_platform_data *pdata, local_pdata;
unsigned addr;
int chips = 0;
struct mcp23s08_driver_data *data;
int status, type;
unsigned ngpio = 0;
const struct of_device_id *match;
match = of_match_device(of_match_ptr(mcp23s08_spi_of_match), &spi->dev);
if (match)
type = (int)(uintptr_t)match->data;
else
type = spi_get_device_id(spi)->driver_data;
pdata = dev_get_platdata(&spi->dev);
if (!pdata) {
pdata = &local_pdata;
pdata->base = -1;
status = device_property_read_u32(&spi->dev,
"microchip,spi-present-mask", &pdata->spi_present_mask);
if (status) {
status = device_property_read_u32(&spi->dev,
"mcp,spi-present-mask",
&pdata->spi_present_mask);
if (status) {
dev_err(&spi->dev, "missing spi-present-mask");
return -ENODEV;
}
}
}
if (!pdata->spi_present_mask || pdata->spi_present_mask > 0xff) {
dev_err(&spi->dev, "invalid spi-present-mask");
return -ENODEV;
}
for (addr = 0; addr < MCP_MAX_DEV_PER_CS; addr++) {
if (pdata->spi_present_mask & BIT(addr))
chips++;
}
if (!chips)
return -ENODEV;
data = devm_kzalloc(&spi->dev,
struct_size(data, chip, chips), GFP_KERNEL);
if (!data)
return -ENOMEM;
spi_set_drvdata(spi, data);
for (addr = 0; addr < MCP_MAX_DEV_PER_CS; addr++) {
if (!(pdata->spi_present_mask & BIT(addr)))
continue;
chips--;
data->mcp[addr] = &data->chip[chips];
data->mcp[addr]->irq = spi->irq;
data->mcp[addr]->irq_chip.name = dev_name(&spi->dev);
data->mcp[addr]->irq_chip.irq_mask = mcp23s08_irq_mask;
data->mcp[addr]->irq_chip.irq_unmask = mcp23s08_irq_unmask;
data->mcp[addr]->irq_chip.irq_set_type = mcp23s08_irq_set_type;
data->mcp[addr]->irq_chip.irq_bus_lock = mcp23s08_irq_bus_lock;
data->mcp[addr]->irq_chip.irq_bus_sync_unlock =
mcp23s08_irq_bus_unlock;
status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi,
0x40 | (addr << 1), type,
pdata->base, addr);
if (status < 0)
return status;
if (pdata->base != -1)
pdata->base += data->mcp[addr]->chip.ngpio;
ngpio += data->mcp[addr]->chip.ngpio;
}
data->ngpio = ngpio;
return 0;
}
static const struct spi_device_id mcp23s08_ids[] = {
{ "mcp23s08", MCP_TYPE_S08 },
{ "mcp23s17", MCP_TYPE_S17 },
{ "mcp23s18", MCP_TYPE_S18 },
{ },
};
MODULE_DEVICE_TABLE(spi, mcp23s08_ids);
static struct spi_driver mcp23s08_driver = {
.probe = mcp23s08_probe,
.id_table = mcp23s08_ids,
.driver = {
.name = "mcp23s08",
.of_match_table = of_match_ptr(mcp23s08_spi_of_match),
},
};
static int __init mcp23s08_spi_init(void)
{
return spi_register_driver(&mcp23s08_driver);
}
static void mcp23s08_spi_exit(void)
{
spi_unregister_driver(&mcp23s08_driver);
}
#else
static int __init mcp23s08_spi_init(void) { return 0; }
static void mcp23s08_spi_exit(void) { }
#endif /* CONFIG_SPI_MASTER */
/*----------------------------------------------------------------------*/
static int __init mcp23s08_init(void)
{
int ret;
ret = mcp23s08_spi_init();
if (ret)
goto spi_fail;
ret = mcp23s08_i2c_init();
if (ret)
goto i2c_fail;
return 0;
i2c_fail:
mcp23s08_spi_exit();
spi_fail:
return ret;
}
/* register after spi/i2c postcore initcall and before
* subsys initcalls that may rely on these GPIOs
*/
subsys_initcall(mcp23s08_init);
static void __exit mcp23s08_exit(void)
{
mcp23s08_spi_exit();
mcp23s08_i2c_exit();
}
module_exit(mcp23s08_exit);
EXPORT_SYMBOL_GPL(mcp23s08_probe_one);
MODULE_LICENSE("GPL");
/* SPDX-License-Identifier: GPL-2.0-only */
/* MCP23S08 SPI/I2C GPIO driver */
#include <linux/gpio/driver.h>
#include <linux/irq.h>
#include <linux/mutex.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/types.h>
/*
* MCP types supported by driver
*/
#define MCP_TYPE_S08 1
#define MCP_TYPE_S17 2
#define MCP_TYPE_008 3
#define MCP_TYPE_017 4
#define MCP_TYPE_S18 5
#define MCP_TYPE_018 6
struct device;
struct regmap;
struct pinctrl_dev;
struct mcp23s08 {
u8 addr;
bool irq_active_high;
bool reg_shift;
u16 irq_rise;
u16 irq_fall;
int irq;
bool irq_controller;
int cached_gpio;
/* lock protects regmap access with bypass/cache flags */
struct mutex lock;
struct gpio_chip chip;
struct irq_chip irq_chip;
struct regmap *regmap;
struct device *dev;
struct pinctrl_dev *pctldev;
struct pinctrl_desc pinctrl_desc;
};
extern const struct regmap_config mcp23x08_regmap;
extern const struct regmap_config mcp23x17_regmap;
int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
unsigned int addr, unsigned int type, unsigned int base);
// SPDX-License-Identifier: GPL-2.0-only
/* MCP23S08 I2C GPIO driver */
#include <linux/i2c.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include "pinctrl-mcp23s08.h"
static int mcp230xx_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
unsigned int type = id->driver_data;
struct mcp23s08 *mcp;
int ret;
mcp = devm_kzalloc(dev, sizeof(*mcp), GFP_KERNEL);
if (!mcp)
return -ENOMEM;
switch (type) {
case MCP_TYPE_008:
mcp->regmap = devm_regmap_init_i2c(client, &mcp23x08_regmap);
mcp->reg_shift = 0;
mcp->chip.ngpio = 8;
mcp->chip.label = "mcp23008";
break;
case MCP_TYPE_017:
mcp->regmap = devm_regmap_init_i2c(client, &mcp23x17_regmap);
mcp->reg_shift = 1;
mcp->chip.ngpio = 16;
mcp->chip.label = "mcp23017";
break;
case MCP_TYPE_018:
mcp->regmap = devm_regmap_init_i2c(client, &mcp23x17_regmap);
mcp->reg_shift = 1;
mcp->chip.ngpio = 16;
mcp->chip.label = "mcp23018";
break;
default:
dev_err(dev, "invalid device type (%d)\n", type);
return -EINVAL;
}
if (IS_ERR(mcp->regmap))
return PTR_ERR(mcp->regmap);
mcp->irq = client->irq;
mcp->pinctrl_desc.name = "mcp23xxx-pinctrl";
ret = mcp23s08_probe_one(mcp, dev, client->addr, type, -1);
if (ret)
return ret;
i2c_set_clientdata(client, mcp);
return 0;
}
static const struct i2c_device_id mcp230xx_id[] = {
{ "mcp23008", MCP_TYPE_008 },
{ "mcp23017", MCP_TYPE_017 },
{ "mcp23018", MCP_TYPE_018 },
{ }
};
MODULE_DEVICE_TABLE(i2c, mcp230xx_id);
static const struct of_device_id mcp23s08_i2c_of_match[] = {
{
.compatible = "microchip,mcp23008",
.data = (void *) MCP_TYPE_008,
},
{
.compatible = "microchip,mcp23017",
.data = (void *) MCP_TYPE_017,
},
{
.compatible = "microchip,mcp23018",
.data = (void *) MCP_TYPE_018,
},
/* NOTE: The use of the mcp prefix is deprecated and will be removed. */
{
.compatible = "mcp,mcp23008",
.data = (void *) MCP_TYPE_008,
},
{
.compatible = "mcp,mcp23017",
.data = (void *) MCP_TYPE_017,
},
{ }
};
MODULE_DEVICE_TABLE(of, mcp23s08_i2c_of_match);
static struct i2c_driver mcp230xx_driver = {
.driver = {
.name = "mcp230xx",
.of_match_table = mcp23s08_i2c_of_match,
},
.probe = mcp230xx_probe,
.id_table = mcp230xx_id,
};
static int __init mcp23s08_i2c_init(void)
{
return i2c_add_driver(&mcp230xx_driver);
}
/*
* Register after I²C postcore initcall and before
* subsys initcalls that may rely on these GPIOs.
*/
subsys_initcall(mcp23s08_i2c_init);
static void mcp23s08_i2c_exit(void)
{
i2c_del_driver(&mcp230xx_driver);
}
module_exit(mcp23s08_i2c_exit);
MODULE_LICENSE("GPL");
// SPDX-License-Identifier: GPL-2.0-only
/* MCP23S08 SPI GPIO driver */
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include "pinctrl-mcp23s08.h"
#define MCP_MAX_DEV_PER_CS 8
/*
* A given spi_device can represent up to eight mcp23sxx chips
* sharing the same chipselect but using different addresses
* (e.g. chips #0 and #3 might be populated, but not #1 or #2).
* Driver data holds all the per-chip data.
*/
struct mcp23s08_driver_data {
unsigned ngpio;
struct mcp23s08 *mcp[8];
struct mcp23s08 chip[];
};
static int mcp23sxx_spi_write(void *context, const void *data, size_t count)
{
struct mcp23s08 *mcp = context;
struct spi_device *spi = to_spi_device(mcp->dev);
struct spi_message m;
struct spi_transfer t[2] = { { .tx_buf = &mcp->addr, .len = 1, },
{ .tx_buf = data, .len = count, }, };
spi_message_init(&m);
spi_message_add_tail(&t[0], &m);
spi_message_add_tail(&t[1], &m);
return spi_sync(spi, &m);
}
static int mcp23sxx_spi_gather_write(void *context,
const void *reg, size_t reg_size,
const void *val, size_t val_size)
{
struct mcp23s08 *mcp = context;
struct spi_device *spi = to_spi_device(mcp->dev);
struct spi_message m;
struct spi_transfer t[3] = { { .tx_buf = &mcp->addr, .len = 1, },
{ .tx_buf = reg, .len = reg_size, },
{ .tx_buf = val, .len = val_size, }, };
spi_message_init(&m);
spi_message_add_tail(&t[0], &m);
spi_message_add_tail(&t[1], &m);
spi_message_add_tail(&t[2], &m);
return spi_sync(spi, &m);
}
static int mcp23sxx_spi_read(void *context, const void *reg, size_t reg_size,
void *val, size_t val_size)
{
struct mcp23s08 *mcp = context;
struct spi_device *spi = to_spi_device(mcp->dev);
u8 tx[2];
if (reg_size != 1)
return -EINVAL;
tx[0] = mcp->addr | 0x01;
tx[1] = *((u8 *) reg);
return spi_write_then_read(spi, tx, sizeof(tx), val, val_size);
}
static const struct regmap_bus mcp23sxx_spi_regmap = {
.write = mcp23sxx_spi_write,
.gather_write = mcp23sxx_spi_gather_write,
.read = mcp23sxx_spi_read,
};
static int mcp23s08_spi_regmap_init(struct mcp23s08 *mcp, struct device *dev,
unsigned int addr, unsigned int type)
{
const struct regmap_config *config;
struct regmap_config *copy;
const char *name;
switch (type) {
case MCP_TYPE_S08:
mcp->reg_shift = 0;
mcp->chip.ngpio = 8;
mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL, "mcp23s08.%d", addr);
config = &mcp23x08_regmap;
name = devm_kasprintf(dev, GFP_KERNEL, "%d", addr);
break;
case MCP_TYPE_S17:
mcp->reg_shift = 1;
mcp->chip.ngpio = 16;
mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL, "mcp23s17.%d", addr);
config = &mcp23x17_regmap;
name = devm_kasprintf(dev, GFP_KERNEL, "%d", addr);
break;
case MCP_TYPE_S18:
mcp->reg_shift = 1;
mcp->chip.ngpio = 16;
mcp->chip.label = "mcp23s18";
config = &mcp23x17_regmap;
name = config->name;
break;
default:
dev_err(dev, "invalid device type (%d)\n", type);
return -EINVAL;
}
copy = devm_kmemdup(dev, &config, sizeof(config), GFP_KERNEL);
if (!copy)
return -ENOMEM;
copy->name = name;
mcp->regmap = devm_regmap_init(dev, &mcp23sxx_spi_regmap, mcp, copy);
if (IS_ERR(mcp->regmap))
return PTR_ERR(mcp->regmap);
return 0;
}
static int mcp23s08_probe(struct spi_device *spi)
{
struct device *dev = &spi->dev;
struct mcp23s08_driver_data *data;
unsigned long spi_present_mask;
const void *match;
unsigned int addr;
unsigned int ngpio = 0;
int chips;
int type;
int ret;
u32 v;
match = device_get_match_data(dev);
if (match)
type = (int)(uintptr_t)match;
else
type = spi_get_device_id(spi)->driver_data;
ret = device_property_read_u32(dev, "microchip,spi-present-mask", &v);
if (ret) {
ret = device_property_read_u32(dev, "mcp,spi-present-mask", &v);
if (ret) {
dev_err(dev, "missing spi-present-mask");
return ret;
}
}
spi_present_mask = v;
if (!spi_present_mask || spi_present_mask >= BIT(MCP_MAX_DEV_PER_CS)) {
dev_err(dev, "invalid spi-present-mask");
return -ENODEV;
}
chips = hweight_long(spi_present_mask);
data = devm_kzalloc(dev, struct_size(data, chip, chips), GFP_KERNEL);
if (!data)
return -ENOMEM;
spi_set_drvdata(spi, data);
for_each_set_bit(addr, &spi_present_mask, MCP_MAX_DEV_PER_CS) {
data->mcp[addr] = &data->chip[--chips];
data->mcp[addr]->irq = spi->irq;
ret = mcp23s08_spi_regmap_init(data->mcp[addr], dev, addr, type);
if (ret)
return ret;
data->mcp[addr]->pinctrl_desc.name = devm_kasprintf(dev, GFP_KERNEL,
"mcp23xxx-pinctrl.%d",
addr);
if (!data->mcp[addr]->pinctrl_desc.name)
return -ENOMEM;
ret = mcp23s08_probe_one(data->mcp[addr], dev, 0x40 | (addr << 1), type, -1);
if (ret < 0)
return ret;
ngpio += data->mcp[addr]->chip.ngpio;
}
data->ngpio = ngpio;
return 0;
}
static const struct spi_device_id mcp23s08_ids[] = {
{ "mcp23s08", MCP_TYPE_S08 },
{ "mcp23s17", MCP_TYPE_S17 },
{ "mcp23s18", MCP_TYPE_S18 },
{ }
};
MODULE_DEVICE_TABLE(spi, mcp23s08_ids);
static const struct of_device_id mcp23s08_spi_of_match[] = {
{
.compatible = "microchip,mcp23s08",
.data = (void *) MCP_TYPE_S08,
},
{
.compatible = "microchip,mcp23s17",
.data = (void *) MCP_TYPE_S17,
},
{
.compatible = "microchip,mcp23s18",
.data = (void *) MCP_TYPE_S18,
},
/* NOTE: The use of the mcp prefix is deprecated and will be removed. */
{
.compatible = "mcp,mcp23s08",
.data = (void *) MCP_TYPE_S08,
},
{
.compatible = "mcp,mcp23s17",
.data = (void *) MCP_TYPE_S17,
},
{ }
};
MODULE_DEVICE_TABLE(of, mcp23s08_spi_of_match);
static struct spi_driver mcp23s08_driver = {
.probe = mcp23s08_probe,
.id_table = mcp23s08_ids,
.driver = {
.name = "mcp23s08",
.of_match_table = mcp23s08_spi_of_match,
},
};
static int __init mcp23s08_spi_init(void)
{
return spi_register_driver(&mcp23s08_driver);
}
/*
* Register after SPI postcore initcall and before
* subsys initcalls that may rely on these GPIOs.
*/
subsys_initcall(mcp23s08_spi_init);
static void mcp23s08_spi_exit(void)
{
spi_unregister_driver(&mcp23s08_driver);
}
module_exit(mcp23s08_spi_exit);
MODULE_LICENSE("GPL");
......@@ -46,32 +46,15 @@ enum {
FUNC_IRQ0_OUT,
FUNC_IRQ1_IN,
FUNC_IRQ1_OUT,
FUNC_MIIM1,
FUNC_MIIM2,
FUNC_MIIM,
FUNC_PCI_WAKE,
FUNC_PTP0,
FUNC_PTP1,
FUNC_PTP2,
FUNC_PTP3,
FUNC_PWM,
FUNC_RECO_CLK0,
FUNC_RECO_CLK1,
FUNC_SFP0,
FUNC_SFP1,
FUNC_SFP2,
FUNC_SFP3,
FUNC_SFP4,
FUNC_SFP5,
FUNC_SFP6,
FUNC_SFP7,
FUNC_SFP8,
FUNC_SFP9,
FUNC_SFP10,
FUNC_SFP11,
FUNC_SFP12,
FUNC_SFP13,
FUNC_SFP14,
FUNC_SFP15,
FUNC_RECO_CLK,
FUNC_SFP,
FUNC_SG0,
FUNC_SG1,
FUNC_SG2,
......@@ -92,32 +75,15 @@ static const char *const ocelot_function_names[] = {
[FUNC_IRQ0_OUT] = "irq0_out",
[FUNC_IRQ1_IN] = "irq1_in",
[FUNC_IRQ1_OUT] = "irq1_out",
[FUNC_MIIM1] = "miim1",
[FUNC_MIIM2] = "miim2",
[FUNC_MIIM] = "miim",
[FUNC_PCI_WAKE] = "pci_wake",
[FUNC_PTP0] = "ptp0",
[FUNC_PTP1] = "ptp1",
[FUNC_PTP2] = "ptp2",
[FUNC_PTP3] = "ptp3",
[FUNC_PWM] = "pwm",
[FUNC_RECO_CLK0] = "reco_clk0",
[FUNC_RECO_CLK1] = "reco_clk1",
[FUNC_SFP0] = "sfp0",
[FUNC_SFP1] = "sfp1",
[FUNC_SFP2] = "sfp2",
[FUNC_SFP3] = "sfp3",
[FUNC_SFP4] = "sfp4",
[FUNC_SFP5] = "sfp5",
[FUNC_SFP6] = "sfp6",
[FUNC_SFP7] = "sfp7",
[FUNC_SFP8] = "sfp8",
[FUNC_SFP9] = "sfp9",
[FUNC_SFP10] = "sfp10",
[FUNC_SFP11] = "sfp11",
[FUNC_SFP12] = "sfp12",
[FUNC_SFP13] = "sfp13",
[FUNC_SFP14] = "sfp14",
[FUNC_SFP15] = "sfp15",
[FUNC_RECO_CLK] = "reco_clk",
[FUNC_SFP] = "sfp",
[FUNC_SG0] = "sg0",
[FUNC_SG1] = "sg1",
[FUNC_SG2] = "sg2",
......@@ -168,18 +134,18 @@ OCELOT_P(6, UART, TWI_SCL_M, NONE);
OCELOT_P(7, UART, TWI_SCL_M, NONE);
OCELOT_P(8, SI, TWI_SCL_M, IRQ0_OUT);
OCELOT_P(9, SI, TWI_SCL_M, IRQ1_OUT);
OCELOT_P(10, PTP2, TWI_SCL_M, SFP0);
OCELOT_P(11, PTP3, TWI_SCL_M, SFP1);
OCELOT_P(12, UART2, TWI_SCL_M, SFP2);
OCELOT_P(13, UART2, TWI_SCL_M, SFP3);
OCELOT_P(14, MIIM1, TWI_SCL_M, SFP4);
OCELOT_P(15, MIIM1, TWI_SCL_M, SFP5);
OCELOT_P(10, PTP2, TWI_SCL_M, SFP);
OCELOT_P(11, PTP3, TWI_SCL_M, SFP);
OCELOT_P(12, UART2, TWI_SCL_M, SFP);
OCELOT_P(13, UART2, TWI_SCL_M, SFP);
OCELOT_P(14, MIIM, TWI_SCL_M, SFP);
OCELOT_P(15, MIIM, TWI_SCL_M, SFP);
OCELOT_P(16, TWI, NONE, SI);
OCELOT_P(17, TWI, TWI_SCL_M, SI);
OCELOT_P(18, PTP0, TWI_SCL_M, NONE);
OCELOT_P(19, PTP1, TWI_SCL_M, NONE);
OCELOT_P(20, RECO_CLK0, TACHO, NONE);
OCELOT_P(21, RECO_CLK1, PWM, NONE);
OCELOT_P(20, RECO_CLK, TACHO, TWI_SCL_M);
OCELOT_P(21, RECO_CLK, PWM, TWI_SCL_M);
#define OCELOT_PIN(n) { \
.number = n, \
......@@ -264,22 +230,22 @@ JAGUAR2_P(40, NONE, TWI_SCL_M);
JAGUAR2_P(41, NONE, TWI_SCL_M);
JAGUAR2_P(42, NONE, TWI_SCL_M);
JAGUAR2_P(43, NONE, TWI_SCL_M);
JAGUAR2_P(44, NONE, SFP8);
JAGUAR2_P(45, NONE, SFP9);
JAGUAR2_P(46, NONE, SFP10);
JAGUAR2_P(47, NONE, SFP11);
JAGUAR2_P(48, SFP0, NONE);
JAGUAR2_P(49, SFP1, SI);
JAGUAR2_P(50, SFP2, SI);
JAGUAR2_P(51, SFP3, SI);
JAGUAR2_P(52, SFP4, NONE);
JAGUAR2_P(53, SFP5, NONE);
JAGUAR2_P(54, SFP6, NONE);
JAGUAR2_P(55, SFP7, NONE);
JAGUAR2_P(56, MIIM1, SFP12);
JAGUAR2_P(57, MIIM1, SFP13);
JAGUAR2_P(58, MIIM2, SFP14);
JAGUAR2_P(59, MIIM2, SFP15);
JAGUAR2_P(44, NONE, SFP);
JAGUAR2_P(45, NONE, SFP);
JAGUAR2_P(46, NONE, SFP);
JAGUAR2_P(47, NONE, SFP);
JAGUAR2_P(48, SFP, NONE);
JAGUAR2_P(49, SFP, SI);
JAGUAR2_P(50, SFP, SI);
JAGUAR2_P(51, SFP, SI);
JAGUAR2_P(52, SFP, NONE);
JAGUAR2_P(53, SFP, NONE);
JAGUAR2_P(54, SFP, NONE);
JAGUAR2_P(55, SFP, NONE);
JAGUAR2_P(56, MIIM, SFP);
JAGUAR2_P(57, MIIM, SFP);
JAGUAR2_P(58, MIIM, SFP);
JAGUAR2_P(59, MIIM, SFP);
JAGUAR2_P(60, NONE, NONE);
JAGUAR2_P(61, NONE, NONE);
JAGUAR2_P(62, NONE, NONE);
......@@ -714,11 +680,12 @@ static void ocelot_irq_handler(struct irq_desc *desc)
struct irq_chip *parent_chip = irq_desc_get_chip(desc);
struct gpio_chip *chip = irq_desc_get_handler_data(desc);
struct ocelot_pinctrl *info = gpiochip_get_data(chip);
unsigned int id_reg = OCELOT_GPIO_INTR_IDENT * info->stride;
unsigned int reg = 0, irq, i;
unsigned long irqs;
for (i = 0; i < info->stride; i++) {
regmap_read(info->map, OCELOT_GPIO_INTR_IDENT + 4 * i, &reg);
regmap_read(info->map, id_reg + 4 * i, &reg);
if (!reg)
continue;
......@@ -751,21 +718,21 @@ static int ocelot_gpiochip_register(struct platform_device *pdev,
gc->of_node = info->dev->of_node;
gc->label = "ocelot-gpio";
irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
if (irq <= 0)
return irq;
girq = &gc->irq;
girq->chip = &ocelot_irqchip;
girq->parent_handler = ocelot_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(&pdev->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_edge_irq;
irq = irq_of_parse_and_map(gc->of_node, 0);
if (irq) {
girq = &gc->irq;
girq->chip = &ocelot_irqchip;
girq->parent_handler = ocelot_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(&pdev->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_edge_irq;
}
ret = devm_gpiochip_add_data(&pdev->dev, gc, info);
if (ret)
......
......@@ -73,7 +73,7 @@ struct rk805_pctrl_info {
int num_pin_groups;
const struct pinctrl_pin_desc *pins;
unsigned int num_pins;
struct rk805_pin_config *pin_cfg;
const struct rk805_pin_config *pin_cfg;
};
enum rk805_pinmux_option {
......@@ -121,7 +121,7 @@ static const struct rk805_pin_group rk805_pin_groups[] = {
#define RK805_GPIO0_VAL_MSK BIT(0)
#define RK805_GPIO1_VAL_MSK BIT(1)
static struct rk805_pin_config rk805_gpio_cfgs[] = {
static const struct rk805_pin_config rk805_gpio_cfgs[] = {
{
.reg = RK805_OUT_REG,
.val_msk = RK805_GPIO0_VAL_MSK,
......
......@@ -508,8 +508,8 @@ static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev,
}
map_num += grp->npins;
new_map = devm_kcalloc(pctldev->dev, map_num, sizeof(*new_map),
GFP_KERNEL);
new_map = kcalloc(map_num, sizeof(*new_map), GFP_KERNEL);
if (!new_map)
return -ENOMEM;
......@@ -519,7 +519,7 @@ static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev,
/* create mux map */
parent = of_get_parent(np);
if (!parent) {
devm_kfree(pctldev->dev, new_map);
kfree(new_map);
return -EINVAL;
}
new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
......@@ -546,6 +546,7 @@ static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev,
static void rockchip_dt_free_map(struct pinctrl_dev *pctldev,
struct pinctrl_map *map, unsigned num_maps)
{
kfree(map);
}
static const struct pinctrl_ops rockchip_pctrl_ops = {
......@@ -2940,14 +2941,14 @@ static int rockchip_pinctrl_parse_dt(struct platform_device *pdev,
sizeof(struct rockchip_pmx_func),
GFP_KERNEL);
if (!info->functions)
return -EINVAL;
return -ENOMEM;
info->groups = devm_kcalloc(dev,
info->ngroups,
sizeof(struct rockchip_pin_group),
GFP_KERNEL);
if (!info->groups)
return -EINVAL;
return -ENOMEM;
i = 0;
......
......@@ -93,7 +93,7 @@ struct rza1_bidir_entry {
};
/**
* rza1_swio_pin - describe a single pin that needs bidir flag applied.
* rza1_swio_pin - describe a single pin that needs swio flag applied.
*/
struct rza1_swio_pin {
u16 pin: 4;
......@@ -418,7 +418,7 @@ static const struct rza1_bidir_entry rza1l_bidir_entries[RZA1_NPORTS] = {
};
static const struct rza1_swio_entry rza1l_swio_entries[] = {
[0] = { ARRAY_SIZE(rza1h_swio_pins), rza1h_swio_pins },
[0] = { ARRAY_SIZE(rza1l_swio_pins), rza1l_swio_pins },
};
/* RZ/A1L (r7s72102x) pinmux flags table */
......
......@@ -288,7 +288,7 @@ static int stmfx_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
struct pinctrl_gpio_range *range;
enum pin_config_param param;
u32 arg;
int dir, i, ret;
int i, ret;
range = pinctrl_find_gpio_range_from_pin_nolock(pctldev, pin);
if (!range) {
......@@ -296,10 +296,6 @@ static int stmfx_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
return -EINVAL;
}
dir = stmfx_gpio_get_direction(&pctl->gpio_chip, pin);
if (dir < 0)
return dir;
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
......
......@@ -988,7 +988,7 @@ static unsigned int sx150x_maybe_swizzle(struct sx150x_pinctrl *pctl,
/*
* In order to mask the differences between 16 and 8 bit expander
* devices we set up a sligthly ficticious regmap that pretends to be
* a set of 32-bit (to accomodate RegSenseLow/RegSenseHigh
* a set of 32-bit (to accommodate RegSenseLow/RegSenseHigh
* pair/quartet) registers and transparently reconstructs those
* registers via multiple I2C/SMBus reads
*
......
......@@ -425,15 +425,6 @@ int pxa2xx_pinctrl_init(struct platform_device *pdev,
}
EXPORT_SYMBOL_GPL(pxa2xx_pinctrl_init);
int pxa2xx_pinctrl_exit(struct platform_device *pdev)
{
struct pxa_pinctrl *pctl = platform_get_drvdata(pdev);
pinctrl_unregister(pctl->pctl_dev);
return 0;
}
EXPORT_SYMBOL_GPL(pxa2xx_pinctrl_exit);
MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
MODULE_DESCRIPTION("Marvell PXA2xx pinctrl driver");
MODULE_LICENSE("GPL v2");
......@@ -216,4 +216,13 @@ config PINCTRL_SM8150
Qualcomm Technologies Inc TLMM block found on the Qualcomm
Technologies Inc SM8150 platform.
config PINCTRL_SM8250
tristate "Qualcomm Technologies Inc SM8250 pin controller driver"
depends on GPIOLIB && OF
select PINCTRL_MSM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm Technologies Inc TLMM block found on the Qualcomm
Technologies Inc SM8250 platform.
endif
......@@ -26,3 +26,4 @@ obj-$(CONFIG_PINCTRL_SC7180) += pinctrl-sc7180.o
obj-$(CONFIG_PINCTRL_SDM660) += pinctrl-sdm660.o
obj-$(CONFIG_PINCTRL_SDM845) += pinctrl-sdm845.o
obj-$(CONFIG_PINCTRL_SM8150) += pinctrl-sm8150.o
obj-$(CONFIG_PINCTRL_SM8250) += pinctrl-sm8250.o
......@@ -23,7 +23,6 @@
#include <linux/pm.h>
#include <linux/log2.h>
#include <linux/qcom_scm.h>
#include <linux/io.h>
#include <linux/soc/qcom/irq.h>
......
此差异已折叠。
......@@ -40,6 +40,8 @@ struct exynos_irq_chip {
u32 eint_pend;
u32 eint_wake_mask_value;
u32 eint_wake_mask_reg;
void (*set_eint_wakeup_mask)(struct samsung_pinctrl_drv_data *drvdata,
struct exynos_irq_chip *irq_chip);
};
static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip)
......@@ -265,6 +267,7 @@ struct exynos_eint_gpio_save {
u32 eint_con;
u32 eint_fltcon0;
u32 eint_fltcon1;
u32 eint_mask;
};
/*
......@@ -342,6 +345,47 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
return 0;
}
static void
exynos_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
struct exynos_irq_chip *irq_chip)
{
struct regmap *pmu_regs;
if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) {
dev_warn(drvdata->dev,
"No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n");
return;
}
pmu_regs = drvdata->retention_ctrl->priv;
dev_info(drvdata->dev,
"Setting external wakeup interrupt mask: 0x%x\n",
irq_chip->eint_wake_mask_value);
regmap_write(pmu_regs, irq_chip->eint_wake_mask_reg,
irq_chip->eint_wake_mask_value);
}
static void
s5pv210_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
struct exynos_irq_chip *irq_chip)
{
void __iomem *clk_base;
if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) {
dev_warn(drvdata->dev,
"No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n");
return;
}
clk_base = (void __iomem *) drvdata->retention_ctrl->priv;
__raw_writel(irq_chip->eint_wake_mask_value,
clk_base + irq_chip->eint_wake_mask_reg);
}
/*
* irq_chip for wakeup interrupts
*/
......@@ -360,8 +404,9 @@ static const struct exynos_irq_chip s5pv210_wkup_irq_chip __initconst = {
.eint_mask = EXYNOS_WKUP_EMASK_OFFSET,
.eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
.eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED,
/* Only difference with exynos4210_wkup_irq_chip: */
/* Only differences with exynos4210_wkup_irq_chip: */
.eint_wake_mask_reg = S5PV210_EINT_WAKEUP_MASK,
.set_eint_wakeup_mask = s5pv210_pinctrl_set_eint_wakeup_mask,
};
static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst = {
......@@ -380,6 +425,7 @@ static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst = {
.eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
.eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED,
.eint_wake_mask_reg = EXYNOS_EINT_WAKEUP_MASK,
.set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask,
};
static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst = {
......@@ -398,6 +444,7 @@ static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst = {
.eint_pend = EXYNOS7_WKUP_EPEND_OFFSET,
.eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED,
.eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK,
.set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask,
};
/* list of external wakeup controllers supported */
......@@ -574,27 +621,6 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
return 0;
}
static void
exynos_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
struct exynos_irq_chip *irq_chip)
{
struct regmap *pmu_regs;
if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) {
dev_warn(drvdata->dev,
"No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n");
return;
}
pmu_regs = drvdata->retention_ctrl->priv;
dev_info(drvdata->dev,
"Setting external wakeup interrupt mask: 0x%x\n",
irq_chip->eint_wake_mask_value);
regmap_write(pmu_regs, irq_chip->eint_wake_mask_reg,
irq_chip->eint_wake_mask_value);
}
static void exynos_pinctrl_suspend_bank(
struct samsung_pinctrl_drv_data *drvdata,
struct samsung_pin_bank *bank)
......@@ -608,10 +634,13 @@ static void exynos_pinctrl_suspend_bank(
+ 2 * bank->eint_offset);
save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+ 2 * bank->eint_offset + 4);
save->eint_mask = readl(regs + bank->irq_chip->eint_mask
+ bank->eint_offset);
pr_debug("%s: save con %#010x\n", bank->name, save->eint_con);
pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0);
pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1);
pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask);
}
void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
......@@ -626,8 +655,8 @@ void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
else if (bank->eint_type == EINT_TYPE_WKUP) {
if (!irq_chip) {
irq_chip = bank->irq_chip;
exynos_pinctrl_set_eint_wakeup_mask(drvdata,
irq_chip);
irq_chip->set_eint_wakeup_mask(drvdata,
irq_chip);
} else if (bank->irq_chip != irq_chip) {
dev_warn(drvdata->dev,
"More than one external wakeup interrupt chip configured (bank: %s). This is not supported by hardware nor by driver.\n",
......@@ -653,6 +682,9 @@ static void exynos_pinctrl_resume_bank(
pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name,
readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+ 2 * bank->eint_offset + 4), save->eint_fltcon1);
pr_debug("%s: mask %#010x => %#010x\n", bank->name,
readl(regs + bank->irq_chip->eint_mask
+ bank->eint_offset), save->eint_mask);
writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET
+ bank->eint_offset);
......@@ -660,6 +692,8 @@ static void exynos_pinctrl_resume_bank(
+ 2 * bank->eint_offset);
writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET
+ 2 * bank->eint_offset + 4);
writel(save->eint_mask, regs + bank->irq_chip->eint_mask
+ bank->eint_offset);
}
void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
......
......@@ -12,6 +12,7 @@ config PINCTRL_SH_PFC
select PINCTRL_PFC_EMEV2 if ARCH_EMEV2
select PINCTRL_PFC_R8A73A4 if ARCH_R8A73A4
select PINCTRL_PFC_R8A7740 if ARCH_R8A7740
select PINCTRL_PFC_R8A7742 if ARCH_R8A7742
select PINCTRL_PFC_R8A7743 if ARCH_R8A7743
select PINCTRL_PFC_R8A7744 if ARCH_R8A7744
select PINCTRL_PFC_R8A7745 if ARCH_R8A7745
......@@ -74,6 +75,9 @@ config PINCTRL_PFC_R8A7740
bool "R-Mobile A1 pin control support" if COMPILE_TEST
select PINCTRL_SH_PFC_GPIO
config PINCTRL_PFC_R8A7742
bool "RZ/G1H pin control support" if COMPILE_TEST
config PINCTRL_PFC_R8A7743
bool "RZ/G1M pin control support" if COMPILE_TEST
......
......@@ -4,6 +4,7 @@ obj-$(CONFIG_PINCTRL_SH_PFC_GPIO) += gpio.o
obj-$(CONFIG_PINCTRL_PFC_EMEV2) += pfc-emev2.o
obj-$(CONFIG_PINCTRL_PFC_R8A73A4) += pfc-r8a73a4.o
obj-$(CONFIG_PINCTRL_PFC_R8A7740) += pfc-r8a7740.o
obj-$(CONFIG_PINCTRL_PFC_R8A7742) += pfc-r8a7790.o
obj-$(CONFIG_PINCTRL_PFC_R8A7743) += pfc-r8a7791.o
obj-$(CONFIG_PINCTRL_PFC_R8A7744) += pfc-r8a7791.o
obj-$(CONFIG_PINCTRL_PFC_R8A7745) += pfc-r8a7794.o
......
......@@ -485,6 +485,12 @@ static const struct of_device_id sh_pfc_of_table[] = {
.data = &r8a7740_pinmux_info,
},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7742
{
.compatible = "renesas,pfc-r8a7742",
.data = &r8a7742_pinmux_info,
},
#endif
#ifdef CONFIG_PINCTRL_PFC_R8A7743
{
.compatible = "renesas,pfc-r8a7743",
......
......@@ -1963,8 +1963,9 @@ static const struct pinmux_func pinmux_func_gpios[] = {
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
/* "name" addr register_size Field_Width */
/* where Field_Width is 1 for single mode registers or 4 for upto 16
mode registers and modes are described in assending order [0..16] */
/* where Field_Width is 1 for single mode registers or 4 for up to 16
* mode registers and modes are described in assending order [0..15]
*/
{ PINMUX_CFG_REG("PAIOR0", 0xfffe3812, 16, 1, GROUP(
0, 0, 0, 0, 0, 0, 0, 0,
......
......@@ -304,6 +304,7 @@ struct sh_pfc_soc_info {
extern const struct sh_pfc_soc_info emev2_pinmux_info;
extern const struct sh_pfc_soc_info r8a73a4_pinmux_info;
extern const struct sh_pfc_soc_info r8a7740_pinmux_info;
extern const struct sh_pfc_soc_info r8a7742_pinmux_info;
extern const struct sh_pfc_soc_info r8a7743_pinmux_info;
extern const struct sh_pfc_soc_info r8a7744_pinmux_info;
extern const struct sh_pfc_soc_info r8a7745_pinmux_info;
......
......@@ -794,13 +794,17 @@ static int sirfsoc_gpio_probe(struct device_node *np)
return -ENODEV;
sgpio = devm_kzalloc(&pdev->dev, sizeof(*sgpio), GFP_KERNEL);
if (!sgpio)
return -ENOMEM;
if (!sgpio) {
err = -ENOMEM;
goto out_put_device;
}
spin_lock_init(&sgpio->lock);
regs = of_iomap(np, 0);
if (!regs)
return -ENOMEM;
if (!regs) {
err = -ENOMEM;
goto out_put_device;
}
sgpio->chip.gc.request = sirfsoc_gpio_request;
sgpio->chip.gc.free = sirfsoc_gpio_free;
......@@ -824,8 +828,10 @@ static int sirfsoc_gpio_probe(struct device_node *np)
girq->parents = devm_kcalloc(&pdev->dev, SIRFSOC_GPIO_NO_OF_BANKS,
sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
if (!girq->parents) {
err = -ENOMEM;
goto out_put_device;
}
for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
bank = &sgpio->sgpio_bank[i];
spin_lock_init(&bank->lock);
......@@ -868,6 +874,8 @@ static int sirfsoc_gpio_probe(struct device_node *np)
gpiochip_remove(&sgpio->chip.gc);
out:
iounmap(regs);
out_put_device:
put_device(&pdev->dev);
return err;
}
......
......@@ -68,8 +68,8 @@
#define SLEEP_PULL_UP_MASK 0x1
#define SLEEP_PULL_UP_SHIFT 3
#define PULL_UP_20K (BIT(12) | BIT(7))
#define PULL_UP_4_7K BIT(12)
#define PULL_UP_4_7K (BIT(12) | BIT(7))
#define PULL_UP_20K BIT(7)
#define PULL_UP_MASK 0x21
#define PULL_UP_SHIFT 7
......
......@@ -103,8 +103,11 @@ static int sun8i_a23_r_pinctrl_probe(struct platform_device *pdev)
rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(rstc)) {
dev_err(&pdev->dev, "Reset controller missing\n");
return PTR_ERR(rstc);
ret = PTR_ERR(rstc);
if (ret == -EPROBE_DEFER)
return ret;
dev_err(&pdev->dev, "Reset controller missing err=%d\n", ret);
return ret;
}
ret = reset_control_deassert(rstc);
......
......@@ -123,7 +123,7 @@ static int tegra_xusb_padctl_get_group_pins(struct pinctrl_dev *pinctrl,
unsigned *num_pins)
{
/*
* For the tegra-xusb pad controller groups are synonomous
* For the tegra-xusb pad controller groups are synonymous
* with lanes/pins and there is always one lane/pin per group.
*/
*pins = &pinctrl->desc->pins[group].number;
......
......@@ -94,7 +94,7 @@ static int zx_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
if (data->aon_pin) {
/*
* It's an AON pin, whose mux register offset and bit position
* can be caluculated from pin number. Each register covers 16
* can be calculated from pin number. Each register covers 16
* pins, and each pin occupies 2 bits.
*/
u16 aoffset = pindesc->number / 16 * 4;
......
此差异已折叠。
/* SPDX-License-Identifier: GPL-2.0 */
struct mcp23s08_platform_data {
/* For mcp23s08, up to 4 slaves (numbered 0..3) can share one SPI
* chipselect, each providing 1 gpio_chip instance with 8 gpios.
* For mpc23s17, up to 8 slaves (numbered 0..7) can share one SPI
* chipselect, each providing 1 gpio_chip (port A + port B) with
* 16 gpios.
*/
u32 spi_present_mask;
/* "base" is the number of the first GPIO or -1 for dynamic
* assignment. If there are gaps in chip addressing the GPIO
* numbers are sequential .. so for example if only slaves 0
* and 3 are present, their GPIOs range from base to base+15
* (or base+31 for s17 variant).
*/
unsigned base;
};
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册