Commit ef991796 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pinctrl-v4.16-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 v4.16 kernel cycle.
  Like with GPIO it is actually a bit calm this time.

  Core changes:

   - After lengthy discussions and partly due to my ignorance, we have
     merged a patch making pinctrl_force_default() and
     pinctrl_force_sleep() reprogram the states into the hardware of any
     hogged pins, even if they are already in the desired state.

     This only apply to hogged pins since groups of pins owned by
     drivers need to be managed by each driver, lest they could not do
     things like runtime PM and put pins to sleeping state even if the
     system as a whole is not in sleep.

  New drivers:

   - New driver for the Microsemi Ocelot SoC. This is used in ethernet
     switches.

   - The X-Powers AXP209 GPIO driver was extended to also deal with pin
     control and moved over from the GPIO subsystem. This circuit is a
     mixed-mode integrated circuit which is part of AllWinner designs.

   - New subdriver for the Qualcomm MSM8998 SoC, core of a high end
     mobile devices (phones) chipset.

   - New subdriver for the ST Microelectronics STM32MP157 MPU and
     STM32F769 MCU from the STM32 family.

   - New subdriver for the MediaTek MT7622 SoC. This is used for
     routers, repeater, gateways and such network infrastructure.

   - New subdriver for the NXP (former Freescale) i.MX 6ULL. This SoC
     has multimedia features and target "smart devices", I guess in-car
     entertainment, in-flight entertainment, industrial control panels
     etc.

  General improvements:

   - Incremental improvements on the SH-PFC subdrivers for things like
     the CAN bus.

   - Enable the glitch filter on Baytrail GPIOs used for interrupts.

   - Proper handling of pins to GPIO ranges on the Semtec SX150X

   - An IRQ setup ordering fix on MCP23S08.

   - A good set of janitorial coding style fixes"

* tag 'pinctrl-v4.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (102 commits)
  pinctrl: mcp23s08: fix irq setup order
  pinctrl: Forward declare struct device
  pinctrl: sunxi: Use of_clk_get_parent_count() instead of open coding
  pinctrl: stm32: add STM32F769 MCU support
  pinctrl: sx150x: Add a static gpio/pinctrl pin range mapping
  pinctrl: sx150x: Register pinctrl before adding the gpiochip
  pinctrl: sx150x: Unregister the pinctrl on release
  pinctrl: ingenic: Remove redundant dev_err call in ingenic_pinctrl_probe()
  pinctrl: sprd: Use seq_putc() in sprd_pinconf_group_dbg_show()
  pinctrl: pinmux: Use seq_putc() in pinmux_pins_show()
  pinctrl: abx500: Use seq_putc() in abx500_gpio_dbg_show()
  pinctrl: mediatek: mt7622: align error handling of mtk_hw_get_value call
  pinctrl: mediatek: mt7622: fix potential uninitialized value being returned
  pinctrl: uniphier: refactor drive strength get/set functions
  pinctrl: imx7ulp: constify struct imx_cfg_params_decode
  pinctrl: imx: constify struct imx_pinctrl_soc_info
  pinctrl: imx7d: simplify imx7d_pinctrl_probe
  pinctrl: imx: use struct imx_pinctrl_soc_info as a const
  pinctrl: sunxi-pinctrl: fix pin funtion can not be match correctly.
  pinctrl: qcom: Add msm8998 pinctrl driver
  ...
parents bf644990 02e389e6
......@@ -17,6 +17,9 @@ and generic pin config nodes.
Supported configurations:
- skew-delay is supported on the Ethernet pins
- drive-strength with 4, 8, 12 or 16 mA as argument is supported for
entire groups on the groups "idegrp", "gmii_gmac0_grp", "gmii_gmac1_grp"
and "pcigrp".
Example:
......
......@@ -4,7 +4,8 @@ Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
and usage.
Required properties:
- compatible: "fsl,imx6ul-iomuxc"
- compatible: "fsl,imx6ul-iomuxc" for main IOMUX controller or
"fsl,imx6ull-iomuxc-snvs" for i.MX 6ULL's SNVS IOMUX controller.
- fsl,pins: each entry consists of 6 integers and represents the mux and config
setting for one pin. The first 5 integers <mux_reg conf_reg input_reg mux_val
input_val> are specified using a PIN_FUNC_ID macro, which can be found in
......
Microsemi Ocelot pin controller Device Tree Bindings
----------------------------------------------------
Required properties:
- compatible : Should be "mscc,ocelot-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.
The first cell is the pin number and the
second cell specifies GPIO flags, as defined in
<dt-bindings/gpio/gpio.h>.
- gpio-ranges : Range of pins managed by the GPIO controller.
The ocelot-pinctrl driver uses the generic pin multiplexing and generic pin
configuration documented in pinctrl-bindings.txt.
The following generic properties are supported:
- function
- pins
Example:
gpio: pinctrl@71070034 {
compatible = "mscc,ocelot-pinctrl";
reg = <0x71070034 0x28>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&gpio 0 0 22>;
uart_pins: uart-pins {
pins = "GPIO_6", "GPIO_7";
function = "uart";
};
uart2_pins: uart2-pins {
pins = "GPIO_12", "GPIO_13";
function = "uart2";
};
};
This diff is collapsed.
Qualcomm MSM8998 TLMM block
This binding describes the Top Level Mode Multiplexer block found in the
MSM8998 platform.
- compatible:
Usage: required
Value type: <string>
Definition: must be "qcom,msm8998-pinctrl"
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: the base address and size of the TLMM register space.
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: should specify the TLMM summary IRQ.
- interrupt-controller:
Usage: required
Value type: <none>
Definition: identifies this node as an interrupt controller
- #interrupt-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/interrupt-controller/irq.h>
- gpio-controller:
Usage: required
Value type: <none>
Definition: identifies this node as a gpio controller
- #gpio-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/gpio/gpio.h>
Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
a general description of GPIO and interrupt bindings.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
The pin configuration nodes act as a container for an arbitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin, a group, or a list of pins or groups. This configuration can include the
mux function to select on those pin(s)/group(s), and various pin configuration
parameters, such as pull-up, drive strength, etc.
PIN CONFIGURATION NODES:
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Each subnode only affects those parameters that are explicitly listed. In
other words, a subnode that lists a mux function but no pin configuration
parameters implies no information about any pin configuration parameters.
Similarly, a pin subnode that describes a pullup parameter implies no
information about e.g. the mux function.
The following generic properties as defined in pinctrl-bindings.txt are valid
to specify in a pin configuration subnode:
- pins:
Usage: required
Value type: <string-array>
Definition: List of gpio pins affected by the properties specified in
this subnode.
Valid pins are:
gpio0-gpio149
Supports mux, bias and drive-strength
sdc2_clk, sdc2_cmd, sdc2_data
Supports bias and drive-strength
ufs_reset
Supports bias and drive-strength
- function:
Usage: required
Value type: <string>
Definition: Specify the alternative function to be configured for the
specified pins. Functions are only valid for gpio pins.
Valid values are:
gpio, adsp_ext, agera_pll, atest_char, atest_gpsadc0,
atest_gpsadc1, atest_tsens, atest_tsens2, atest_usb1,
atest_usb10, atest_usb11, atest_usb12, atest_usb13,
audio_ref, bimc_dte0, bimc_dte1, blsp10_spi, blsp10_spi_a,
blsp10_spi_b, blsp11_i2c, blsp1_spi, blsp1_spi_a,
blsp1_spi_b, blsp2_spi, blsp9_spi, blsp_i2c1, blsp_i2c2,
blsp_i2c3, blsp_i2c4, blsp_i2c5, blsp_i2c6, blsp_i2c7,
blsp_i2c8, blsp_i2c9, blsp_i2c10, blsp_i2c11, blsp_i2c12,
blsp_spi1, blsp_spi2, blsp_spi3, blsp_spi4, blsp_spi5,
blsp_spi6, blsp_spi7, blsp_spi8, blsp_spi9, blsp_spi10,
blsp_spi11, blsp_spi12, blsp_uart1_a, blsp_uart1_b,
blsp_uart2_a, blsp_uart2_b, blsp_uart3_a, blsp_uart3_b,
blsp_uart7_a, blsp_uart7_b, blsp_uart8, blsp_uart8_a,
blsp_uart8_b, blsp_uart9_a, blsp_uart9_b, blsp_uim1_a,
blsp_uim1_b, blsp_uim2_a, blsp_uim2_b, blsp_uim3_a,
blsp_uim3_b, blsp_uim7_a, blsp_uim7_b, blsp_uim8_a,
blsp_uim8_b, blsp_uim9_a, blsp_uim9_b, bt_reset,
btfm_slimbus, 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, edp_hot, edp_lcd,
gcc_gp1_a, gcc_gp1_b, gcc_gp2_a, gcc_gp2_b, gcc_gp3_a,
gcc_gp3_b, hdmi_cec, hdmi_ddc, hdmi_hot, hdmi_rcv,
isense_dbg, jitter_bist, ldo_en, ldo_update, lpass_slimbus,
m_voc, mdp_vsync, mdp_vsync0, mdp_vsync1, mdp_vsync2,
mdp_vsync3, mdp_vsync_a, mdp_vsync_b, modem_tsync, mss_lte,
nav_dr, nav_pps, pa_indicator, pci_e0, phase_flag,
pll_bypassnl, pll_reset, pri_mi2s, pri_mi2s_ws, prng_rosc,
pwr_crypto, pwr_modem, pwr_nav, qdss_cti0_a, qdss_cti0_b,
qdss_cti1_a, qdss_cti1_b, qdss, qlink_enable,
qlink_request, qua_mi2s, sd_card, sd_write, sdc40, sdc41,
sdc42, sdc43, sdc4_clk, sdc4_cmd, sec_mi2s, sp_cmu,
spkr_i2s, ssbi1, ssc_irq, ter_mi2s, tgu_ch0, tgu_ch1,
tsense_pwm1, tsense_pwm2, tsif1_clk, tsif1_data, tsif1_en,
tsif1_error, tsif1_sync, tsif2_clk, tsif2_data, tsif2_en,
tsif2_error, tsif2_sync, uim1_clk, uim1_data, uim1_present,
uim1_reset, uim2_clk, uim2_data, uim2_present, uim2_reset,
uim_batt, usb_phy, vfr_1, vsense_clkout, vsense_data0,
vsense_data1, vsense_mode, wlan1_adc0, wlan1_adc1,
wlan2_adc0, wlan2_adc1,
- bias-disable:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as no pull.
- bias-pull-down:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as pull down.
- bias-pull-up:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as pull up.
- output-high:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
high.
Not valid for sdc pins.
- output-low:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
low.
Not valid for sdc pins.
- drive-strength:
Usage: optional
Value type: <u32>
Definition: Selects the drive strength for the specified pins, in mA.
Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16
Example:
tlmm: pinctrl@03400000 {
compatible = "qcom,msm8998-pinctrl";
reg = <0x03400000 0xc00000>;
interrupts = <0 208 0>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
uart_console_active: uart_console_active {
mux {
pins = "gpio4", "gpio5";
function = "blsp_uart8_a";
};
config {
pins = "gpio4", "gpio5";
drive-strength = <2>;
bias-disable;
};
};
};
......@@ -24,6 +24,7 @@ Required Properties:
- "renesas,pfc-r8a7794": for R8A7794 (R-Car E2) compatible pin-controller.
- "renesas,pfc-r8a7795": for R8A7795 (R-Car H3) compatible pin-controller.
- "renesas,pfc-r8a7796": for R8A7796 (R-Car M3-W) compatible pin-controller.
- "renesas,pfc-r8a77970": for R8A77970 (R-Car V3M) compatible pin-controller.
- "renesas,pfc-r8a77995": for R8A77995 (R-Car D3) compatible pin-controller.
- "renesas,pfc-sh73a0": for SH73A0 (SH-Mobile AG5) compatible pin-controller.
......
UniPhier SoCs pin controller
Required properties:
- compatible: should be one of the following:
"socionext,uniphier-ld4-pinctrl" - for LD4 SoC
"socionext,uniphier-pro4-pinctrl" - for Pro4 SoC
"socionext,uniphier-sld8-pinctrl" - for sLD8 SoC
"socionext,uniphier-pro5-pinctrl" - for Pro5 SoC
"socionext,uniphier-pxs2-pinctrl" - for PXs2 SoC
"socionext,uniphier-ld6b-pinctrl" - for LD6b SoC
"socionext,uniphier-ld11-pinctrl" - for LD11 SoC
"socionext,uniphier-ld20-pinctrl" - for LD20 SoC
"socionext,uniphier-pxs3-pinctrl" - for PXs3 SoC
Note:
The UniPhier pinctrl should be a subnode of a "syscon" compatible node.
Example:
soc-glue@5f800000 {
compatible = "socionext,uniphier-pro4-soc-glue",
"simple-mfd", "syscon";
reg = <0x5f800000 0x2000>;
pinctrl: pinctrl {
compatible = "socionext,uniphier-pro4-pinctrl";
};
};
......@@ -12,6 +12,8 @@ Required properies:
"st,stm32f469-pinctrl"
"st,stm32f746-pinctrl"
"st,stm32h743-pinctrl"
"st,stm32mp157-pinctrl"
"st,stm32mp157-z-pinctrl"
- #address-cells: The value of this property must be 1
- #size-cells : The value of this property must be 1
- ranges : defines mapping between pin controller node (parent) to
......
......@@ -2086,6 +2086,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
T: git git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-uniphier.git
S: Maintained
F: Documentation/devicetree/bindings/gpio/gpio-uniphier.txt
F: Documentation/devicetree/bindings/pinctrl/socionext,uniphier-pinctrl.txt
F: arch/arm/boot/dts/uniphier*
F: arch/arm/include/asm/hardware/cache-uniphier.h
F: arch/arm/mach-uniphier/
......@@ -10875,6 +10876,16 @@ M: Heikki Krogerus <heikki.krogerus@linux.intel.com>
S: Maintained
F: drivers/pinctrl/intel/
PIN CONTROLLER - MEDIATEK
M: Sean Wang <sean.wang@mediatek.com>
L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
F: Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
F: drivers/pinctrl/mediatek/pinctrl-mtk-common.*
F: drivers/pinctrl/mediatek/pinctrl-mt2701.c
F: drivers/pinctrl/mediatek/pinctrl-mt7622.c
PIN CONTROLLER - QUALCOMM
M: Bjorn Andersson <bjorn.andersson@linaro.org>
S: Maintained
......
......@@ -505,4 +505,4 @@ module_platform_driver(uniphier_gpio_driver);
MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
MODULE_DESCRIPTION("UniPhier GPIO driver");
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
......@@ -58,58 +58,6 @@ static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
return ACPI_HANDLE(gc->parent) == data;
}
#ifdef CONFIG_PINCTRL
/**
* acpi_gpiochip_pin_to_gpio_offset() - translates ACPI GPIO to Linux GPIO
* @gdev: GPIO device
* @pin: ACPI GPIO pin number from GpioIo/GpioInt resource
*
* Function takes ACPI GpioIo/GpioInt pin number as a parameter and
* translates it to a corresponding offset suitable to be passed to a
* GPIO controller driver.
*
* Typically the returned offset is same as @pin, but if the GPIO
* controller uses pin controller and the mapping is not contiguous the
* offset might be different.
*/
static int acpi_gpiochip_pin_to_gpio_offset(struct gpio_device *gdev, int pin)
{
struct gpio_pin_range *pin_range;
/* If there are no ranges in this chip, use 1:1 mapping */
if (list_empty(&gdev->pin_ranges))
return pin;
list_for_each_entry(pin_range, &gdev->pin_ranges, node) {
const struct pinctrl_gpio_range *range = &pin_range->range;
int i;
if (range->pins) {
for (i = 0; i < range->npins; i++) {
if (range->pins[i] == pin)
return range->base + i - gdev->base;
}
} else {
if (pin >= range->pin_base &&
pin < range->pin_base + range->npins) {
unsigned gpio_base;
gpio_base = range->base - gdev->base;
return gpio_base + pin - range->pin_base;
}
}
}
return -EINVAL;
}
#else
static inline int acpi_gpiochip_pin_to_gpio_offset(struct gpio_device *gdev,
int pin)
{
return pin;
}
#endif
/**
* acpi_get_gpiod() - Translate ACPI GPIO pin to GPIO descriptor usable with GPIO API
* @path: ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
......@@ -125,7 +73,6 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
struct gpio_chip *chip;
acpi_handle handle;
acpi_status status;
int offset;
status = acpi_get_handle(NULL, path, &handle);
if (ACPI_FAILURE(status))
......@@ -135,11 +82,7 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
if (!chip)
return ERR_PTR(-EPROBE_DEFER);
offset = acpi_gpiochip_pin_to_gpio_offset(chip->gpiodev, pin);
if (offset < 0)
return ERR_PTR(offset);
return gpiochip_get_desc(chip, offset);
return gpiochip_get_desc(chip, pin);
}
static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)
......@@ -216,10 +159,6 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
if (!handler)
return AE_OK;
pin = acpi_gpiochip_pin_to_gpio_offset(chip->gpiodev, pin);
if (pin < 0)
return AE_BAD_PARAMETER;
desc = gpiochip_request_own_desc(chip, pin, "ACPI:Event");
if (IS_ERR(desc)) {
dev_err(chip->parent, "Failed to request GPIO\n");
......@@ -871,12 +810,6 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
struct gpio_desc *desc;
bool found;
pin = acpi_gpiochip_pin_to_gpio_offset(chip->gpiodev, pin);
if (pin < 0) {
status = AE_BAD_PARAMETER;
goto out;
}
mutex_lock(&achip->conn_lock);
found = false;
......@@ -1009,11 +942,7 @@ static struct gpio_desc *acpi_gpiochip_parse_own_gpio(
if (ret < 0)
return ERR_PTR(ret);
ret = acpi_gpiochip_pin_to_gpio_offset(chip->gpiodev, gpios[0]);
if (ret < 0)
return ERR_PTR(ret);
desc = gpiochip_get_desc(chip, ret);
desc = gpiochip_get_desc(chip, gpios[0]);
if (IS_ERR(desc))
return desc;
......
......@@ -66,6 +66,10 @@ config PINCTRL_AS3722
config PINCTRL_AXP209
tristate "X-Powers AXP209 PMIC pinctrl and GPIO Support"
depends on MFD_AXP20X
depends on OF
select PINMUX
select GENERIC_PINCONF
select GPIOLIB
help
AXP PMICs provides multiple GPIOs that can be muxed for different
functions. This driver bundles a pinctrl driver to select the function
......@@ -353,6 +357,17 @@ config PINCTRL_RK805
help
This selects the pinctrl driver for RK805.
config PINCTRL_OCELOT
bool "Pinctrl driver for the Microsemi Ocelot SoCs"
default y
depends on OF
depends on MSCC_OCELOT || COMPILE_TEST
select GPIOLIB
select GENERIC_PINCONF
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
select REGMAP_MMIO
source "drivers/pinctrl/aspeed/Kconfig"
source "drivers/pinctrl/bcm/Kconfig"
source "drivers/pinctrl/berlin/Kconfig"
......
......@@ -46,6 +46,7 @@ obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o
obj-$(CONFIG_PINCTRL_INGENIC) += pinctrl-ingenic.o
obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o
obj-$(CONFIG_PINCTRL_OCELOT) += pinctrl-ocelot.o
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
obj-y += bcm/
......@@ -65,5 +66,5 @@ obj-$(CONFIG_PINCTRL_SUNXI) += sunxi/
obj-y += ti/
obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
obj-$(CONFIG_ARCH_VT8500) += vt8500/
obj-$(CONFIG_PINCTRL_MTK) += mediatek/
obj-y += mediatek/
obj-$(CONFIG_PINCTRL_ZX) += zte/
......@@ -1189,19 +1189,16 @@ struct pinctrl_state *pinctrl_lookup_state(struct pinctrl *p,
EXPORT_SYMBOL_GPL(pinctrl_lookup_state);
/**
* pinctrl_select_state() - select/activate/program a pinctrl state to HW
* pinctrl_commit_state() - select/activate/program a pinctrl state to HW
* @p: the pinctrl handle for the device that requests configuration
* @state: the state handle to select/activate/program
*/
int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state)
{
struct pinctrl_setting *setting, *setting2;
struct pinctrl_state *old_state = p->state;
int ret;
if (p->state == state)
return 0;
if (p->state) {
/*
* For each pinmux setting in the old state, forget SW's record
......@@ -1265,6 +1262,19 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
return ret;
}
/**
* pinctrl_select_state() - select/activate/program a pinctrl state to HW
* @p: the pinctrl handle for the device that requests configuration
* @state: the state handle to select/activate/program
*/
int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
{
if (p->state == state)
return 0;
return pinctrl_commit_state(p, state);
}
EXPORT_SYMBOL_GPL(pinctrl_select_state);
static void devm_pinctrl_release(struct device *dev, void *res)
......@@ -1430,7 +1440,7 @@ void pinctrl_unregister_map(const struct pinctrl_map *map)
int pinctrl_force_sleep(struct pinctrl_dev *pctldev)
{
if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_sleep))
return pinctrl_select_state(pctldev->p, pctldev->hog_sleep);
return pinctrl_commit_state(pctldev->p, pctldev->hog_sleep);
return 0;
}
EXPORT_SYMBOL_GPL(pinctrl_force_sleep);
......@@ -1442,7 +1452,7 @@ EXPORT_SYMBOL_GPL(pinctrl_force_sleep);
int pinctrl_force_default(struct pinctrl_dev *pctldev)
{
if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_default))
return pinctrl_select_state(pctldev->p, pctldev->hog_default);
return pinctrl_commit_state(pctldev->p, pctldev->hog_default);
return 0;
}
EXPORT_SYMBOL_GPL(pinctrl_force_default);
......
This diff is collapsed.
......@@ -58,14 +58,10 @@ struct imx_cfg_params_decode {
};
struct imx_pinctrl_soc_info {
struct device *dev;
const struct pinctrl_pin_desc *pins;
unsigned int npins;
struct imx_pin_reg *pin_regs;
unsigned int group_index;
unsigned int flags;
const char *gpr_compatible;
struct mutex mutex;
/* MUX_MODE shift and mask in case SHARE_MUX_CONF_REG */
unsigned int mux_mask;
......@@ -75,7 +71,7 @@ struct imx_pinctrl_soc_info {
bool generic_pinconf;
const struct pinconf_generic_params *custom_params;
unsigned int num_custom_params;
struct imx_cfg_params_decode *decodes;
const struct imx_cfg_params_decode *decodes;
unsigned int num_decodes;
void (*fixup)(unsigned long *configs, unsigned int num_configs,
u32 *raw_config);
......@@ -95,7 +91,10 @@ struct imx_pinctrl {
struct pinctrl_dev *pctl;
void __iomem *base;
void __iomem *input_sel_base;
struct imx_pinctrl_soc_info *info;
const struct imx_pinctrl_soc_info *info;
struct imx_pin_reg *pin_regs;
unsigned int group_index;
struct mutex mutex;
};
#define IMX_CFG_PARAMS_DECODE(p, m, o) \
......@@ -117,5 +116,5 @@ struct imx_pinctrl {
#define IOMUXC_CONFIG_SION (0x1 << 4)
int imx_pinctrl_probe(struct platform_device *pdev,
struct imx_pinctrl_soc_info *info);
const struct imx_pinctrl_soc_info *info);
#endif /* __DRIVERS_PINCTRL_IMX_H */
......@@ -309,7 +309,7 @@ static const struct pinctrl_pin_desc imx25_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX25_PAD_BOOT_MODE1),
};
static struct imx_pinctrl_soc_info imx25_pinctrl_info = {
static const struct imx_pinctrl_soc_info imx25_pinctrl_info = {
.pins = imx25_pinctrl_pads,
.npins = ARRAY_SIZE(imx25_pinctrl_pads),
};
......
......@@ -999,7 +999,7 @@ static const struct pinctrl_pin_desc imx35_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX35_PAD_TEST_MODE),
};
static struct imx_pinctrl_soc_info imx35_pinctrl_info = {
static const struct imx_pinctrl_soc_info imx35_pinctrl_info = {
.pins = imx35_pinctrl_pads,
.npins = ARRAY_SIZE(imx35_pinctrl_pads),
};
......
......@@ -385,7 +385,7 @@ static const struct pinctrl_pin_desc imx50_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX50_PAD_EIM_CRE),
};
static struct imx_pinctrl_soc_info imx50_pinctrl_info = {
static const struct imx_pinctrl_soc_info imx50_pinctrl_info = {
.pins = imx50_pinctrl_pads,
.npins = ARRAY_SIZE(imx50_pinctrl_pads),
.gpr_compatible = "fsl,imx50-iomuxc-gpr",
......
......@@ -762,7 +762,7 @@ static const struct pinctrl_pin_desc imx51_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX51_PAD_CSI1_MCLK),
};
static struct imx_pinctrl_soc_info imx51_pinctrl_info = {
static const struct imx_pinctrl_soc_info imx51_pinctrl_info = {
.pins = imx51_pinctrl_pads,
.npins = ARRAY_SIZE(imx51_pinctrl_pads),
};
......
......@@ -448,7 +448,7 @@ static const struct pinctrl_pin_desc imx53_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX53_PAD_GPIO_18),
};
static struct imx_pinctrl_soc_info imx53_pinctrl_info = {
static const struct imx_pinctrl_soc_info imx53_pinctrl_info = {
.pins = imx53_pinctrl_pads,
.npins = ARRAY_SIZE(imx53_pinctrl_pads),
.gpr_compatible = "fsl,imx53-iomuxc-gpr",
......
......@@ -457,7 +457,7 @@ static const struct pinctrl_pin_desc imx6dl_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX6DL_PAD_SD4_DAT7),
};
static struct imx_pinctrl_soc_info imx6dl_pinctrl_info = {
static const struct imx_pinctrl_soc_info imx6dl_pinctrl_info = {
.pins = imx6dl_pinctrl_pads,
.npins = ARRAY_SIZE(imx6dl_pinctrl_pads),
.gpr_compatible = "fsl,imx6q-iomuxc-gpr",
......
......@@ -460,7 +460,7 @@ static const struct pinctrl_pin_desc imx6q_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX6Q_PAD_SD2_DAT3),
};
static struct imx_pinctrl_soc_info imx6q_pinctrl_info = {
static const struct imx_pinctrl_soc_info imx6q_pinctrl_info = {
.pins = imx6q_pinctrl_pads,
.npins = ARRAY_SIZE(imx6q_pinctrl_pads),
.gpr_compatible = "fsl,imx6q-iomuxc-gpr",
......
......@@ -363,7 +363,7 @@ static const struct pinctrl_pin_desc imx6sl_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX6SL_PAD_WDOG_B),
};
static struct imx_pinctrl_soc_info imx6sl_pinctrl_info = {
static const struct imx_pinctrl_soc_info imx6sl_pinctrl_info = {
.pins = imx6sl_pinctrl_pads,
.npins = ARRAY_SIZE(imx6sl_pinctrl_pads),
.gpr_compatible = "fsl,imx6sl-iomuxc-gpr",
......
......@@ -367,7 +367,7 @@ static const struct pinctrl_pin_desc imx6sx_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX6SX_PAD_USB_H_STROBE),
};
static struct imx_pinctrl_soc_info imx6sx_pinctrl_info = {
static const struct imx_pinctrl_soc_info imx6sx_pinctrl_info = {
.pins = imx6sx_pinctrl_pads,
.npins = ARRAY_SIZE(imx6sx_pinctrl_pads),
.gpr_compatible = "fsl,imx6sx-iomuxc-gpr",
......
......@@ -150,6 +150,21 @@ enum imx6ul_pads {
MX6UL_PAD_CSI_DATA07 = 128,
};
enum imx6ull_lpsr_pads {
MX6ULL_PAD_BOOT_MODE0 = 0,
MX6ULL_PAD_BOOT_MODE1 = 1,
MX6ULL_PAD_SNVS_TAMPER0 = 2,
MX6ULL_PAD_SNVS_TAMPER1 = 3,
MX6ULL_PAD_SNVS_TAMPER2 = 4,
MX6ULL_PAD_SNVS_TAMPER3 = 5,
MX6ULL_PAD_SNVS_TAMPER4 = 6,
MX6ULL_PAD_SNVS_TAMPER5 = 7,
MX6ULL_PAD_SNVS_TAMPER6 = 8,
MX6ULL_PAD_SNVS_TAMPER7 = 9,
MX6ULL_PAD_SNVS_TAMPER8 = 10,
MX6ULL_PAD_SNVS_TAMPER9 = 11,
};
/* Pad names for the pinmux subsystem */
static const struct pinctrl_pin_desc imx6ul_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX6UL_PAD_RESERVE0),
......@@ -283,20 +298,49 @@ static const struct pinctrl_pin_desc imx6ul_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX6UL_PAD_CSI_DATA07),
};
static struct imx_pinctrl_soc_info imx6ul_pinctrl_info = {
/* pad for i.MX6ULL lpsr pinmux */
static const struct pinctrl_pin_desc imx6ull_snvs_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX6ULL_PAD_BOOT_MODE0),
IMX_PINCTRL_PIN(MX6ULL_PAD_BOOT_MODE1),
IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER0),
IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER1),
IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER2),
IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER3),
IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER4),
IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER5),
IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER6),
IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER7),
IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER8),
IMX_PINCTRL_PIN(MX6ULL_PAD_SNVS_TAMPER9),
};
static const struct imx_pinctrl_soc_info imx6ul_pinctrl_info = {
.pins = imx6ul_pinctrl_pads,
.npins = ARRAY_SIZE(imx6ul_pinctrl_pads),
.gpr_compatible = "fsl,imx6ul-iomuxc-gpr",
};
static struct of_device_id imx6ul_pinctrl_of_match[] = {
{ .compatible = "fsl,imx6ul-iomuxc", },
static const struct imx_pinctrl_soc_info imx6ull_snvs_pinctrl_info = {
.pins = imx6ull_snvs_pinctrl_pads,
.npins = ARRAY_SIZE(imx6ull_snvs_pinctrl_pads),
.flags = ZERO_OFFSET_VALID,
};
static const struct of_device_id imx6ul_pinctrl_of_match[] = {
{ .compatible = "fsl,imx6ul-iomuxc", .data = &imx6ul_pinctrl_info, },
{ .compatible = "fsl,imx6ull-iomuxc-snvs", .data = &imx6ull_snvs_pinctrl_info, },
{ /* sentinel */ }
};
static int imx6ul_pinctrl_probe(struct platform_device *pdev)
{
return imx_pinctrl_probe(pdev, &imx6ul_pinctrl_info);
const struct imx_pinctrl_soc_info *pinctrl_info;
pinctrl_info = of_device_get_match_data(&pdev->dev);
if (!pinctrl_info)
return -ENODEV;
return imx_pinctrl_probe(pdev, pinctrl_info);
}
static struct platform_driver imx6ul_pinctrl_driver = {
......
......@@ -378,16 +378,12 @@ static const struct of_device_id imx7d_pinctrl_of_match[] = {
static int imx7d_pinctrl_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
struct imx_pinctrl_soc_info *pinctrl_info;
const struct imx_pinctrl_soc_info *pinctrl_info;
match = of_match_device(imx7d_pinctrl_of_match, &pdev->dev);
if (!match)
pinctrl_info = of_device_get_match_data(&pdev->dev);
if (!pinctrl_info)
return -ENODEV;
pinctrl_info = (struct imx_pinctrl_soc_info *) match->data;
return imx_pinctrl_probe(pdev, pinctrl_info);
}
......
......@@ -266,7 +266,7 @@ static const struct pinctrl_pin_desc imx7ulp_pinctrl_pads[] = {
#define BP_MUX_MODE 8
#define BM_PULL_ENABLED BIT(1)
struct imx_cfg_params_decode imx7ulp_cfg_decodes[] = {
static const struct imx_cfg_params_decode imx7ulp_cfg_decodes[] = {
IMX_CFG_PARAMS_DECODE(PIN_CONFIG_DRIVE_STRENGTH, BIT(6), 6),
IMX_CFG_PARAMS_DECODE(PIN_CONFIG_DRIVE_PUSH_PULL, BIT(5), 5),
IMX_CFG_PARAMS_DECODE(PIN_CONFIG_SLEW_RATE, BIT(2), 2),
......@@ -307,11 +307,10 @@ static int imx7ulp_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
unsigned offset, bool input)
{
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
struct imx_pinctrl_soc_info *info = ipctl->info;
const struct imx_pin_reg *pin_reg;
u32 reg;
pin_reg = &info->pin_regs[offset];
pin_reg = &ipctl->pin_regs[offset];
if (pin_reg->mux_reg == -1)
return -EINVAL;
......@@ -325,7 +324,7 @@ static int imx7ulp_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
return 0;
}
static struct imx_pinctrl_soc_info imx7ulp_pinctrl_info = {
static const struct imx_pinctrl_soc_info imx7ulp_pinctrl_info = {
.pins = imx7ulp_pinctrl_pads,
.npins = ARRAY_SIZE(imx7ulp_pinctrl_pads),
.flags = ZERO_OFFSET_VALID | SHARE_MUX_CONF_REG,
......
......@@ -300,11 +300,10 @@ static int vf610_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
unsigned offset, bool input)
{
struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
struct imx_pinctrl_soc_info *info = ipctl->info;
const struct imx_pin_reg *pin_reg;
u32 reg;
pin_reg = &info->pin_regs[offset];
pin_reg = &ipctl->pin_regs[offset];
if (pin_reg->mux_reg == -1)
return -EINVAL;
......@@ -319,7 +318,7 @@ static int vf610_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
return 0;
}
static struct imx_pinctrl_soc_info vf610_pinctrl_info = {
static const struct imx_pinctrl_soc_info vf610_pinctrl_info = {
.pins = vf610_pinctrl_pads,
.npins = ARRAY_SIZE(vf610_pinctrl_pads),
.flags = SHARE_MUX_CONF_REG | ZERO_OFFSET_VALID,
......
......@@ -46,6 +46,9 @@
#define BYT_TRIG_POS BIT(25)
#define BYT_TRIG_LVL BIT(24)
#define BYT_DEBOUNCE_EN BIT(20)
#define BYT_GLITCH_FILTER_EN BIT(19)
#define BYT_GLITCH_F_SLOW_CLK BIT(17)
#define BYT_GLITCH_F_FAST_CLK BIT(16)
#define BYT_PULL_STR_SHIFT 9
#define BYT_PULL_STR_MASK (3 << BYT_PULL_STR_SHIFT)
#define BYT_PULL_STR_2K (0 << BYT_PULL_STR_SHIFT)
......@@ -1579,6 +1582,9 @@ static int byt_irq_type(struct irq_data *d, unsigned int type)
*/
value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG |
BYT_TRIG_LVL);
/* Enable glitch filtering */
value |= BYT_GLITCH_FILTER_EN | BYT_GLITCH_F_SLOW_CLK |
BYT_GLITCH_F_FAST_CLK;
writel(value, reg);
......
......@@ -23,13 +23,16 @@
#define CNL_HOSTSW_OWN 0x0b0
#define CNL_GPI_IE 0x120
#define CNL_GPP(r, s, e) \
#define CNL_GPP(r, s, e, g) \
{ \
.reg_num = (r), \
.base = (s), \
.size = ((e) - (s) + 1), \
.gpio_base = (g), \
}
#define CNL_NO_GPIO -1
#define CNL_COMMUNITY(b, s, e, g) \
{ \
.barno = (b), \
......@@ -363,32 +366,32 @@ static const struct pinctrl_pin_desc cnlh_pins[] = {
};
static const struct intel_padgroup cnlh_community0_gpps[] = {
CNL_GPP(0, 0, 24), /* GPP_A */
CNL_GPP(1, 25, 50), /* GPP_B */
CNL_GPP(0, 0, 24, 0), /* GPP_A */
CNL_GPP(1, 25, 50, 32), /* GPP_B */
};
static const struct intel_padgroup cnlh_community1_gpps[] = {
CNL_GPP(0, 51, 74), /* GPP_C */
CNL_GPP(1, 75, 98), /* GPP_D */
CNL_GPP(2, 99, 106), /* GPP_G */
CNL_GPP(3, 107, 114), /* AZA */
CNL_GPP(4, 115, 146), /* vGPIO_0 */
CNL_GPP(5, 147, 154), /* 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, CNL_NO_GPIO), /* AZA */
CNL_GPP(4, 115, 146, 160), /* vGPIO_0 */
CNL_GPP(5, 147, 154, CNL_NO_GPIO), /* vGPIO_1 */
};
static const struct intel_padgroup cnlh_community3_gpps[] = {
CNL_GPP(0, 155, 178), /* GPP_K */
CNL_GPP(1, 179, 202), /* GPP_H */
CNL_GPP(2, 203, 215), /* GPP_E */
CNL_GPP(3, 216, 239), /* GPP_F */
CNL_GPP(4, 240, 248), /* SPI */
CNL_GPP(0, 155, 178, 192), /* GPP_K */
CNL_GPP(1, 179, 202, 224), /* GPP_H */
CNL_GPP(2, 203, 215, 258), /* GPP_E */
CNL_GPP(3, 216, 239, 288), /* GPP_F */
CNL_GPP(4, 240, 248, CNL_NO_GPIO), /* SPI */
};
static const struct intel_padgroup cnlh_community4_gpps[] = {
CNL_GPP(0, 249, 259), /* CPU */
CNL_GPP(1, 260, 268), /* JTAG */
CNL_GPP(2, 269, 286), /* GPP_I */
CNL_GPP(3, 287, 298), /* GPP_J */
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 */
};
static const unsigned int cnlh_spi0_pins[] = { 40, 41, 42, 43 };
......@@ -785,25 +788,25 @@ static const struct intel_function cnllp_functions[] = {
};
static const struct intel_padgroup cnllp_community0_gpps[] = {
CNL_GPP(0, 0, 24), /* GPP_A */
CNL_GPP(1, 25, 50), /* GPP_B */
CNL_GPP(2, 51, 58), /* GPP_G */
CNL_GPP(3, 59, 67), /* 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, CNL_NO_GPIO), /* SPI */
};
static const struct intel_padgroup cnllp_community1_gpps[] = {
CNL_GPP(0, 68, 92), /* GPP_D */
CNL_GPP(1, 93, 116), /* GPP_F */
CNL_GPP(2, 117, 140), /* GPP_H */
CNL_GPP(3, 141, 172), /* vGPIO */
CNL_GPP(4, 173, 180), /* 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), /* GPP_C */
CNL_GPP(1, 205, 228), /* GPP_E */
CNL_GPP(2, 229, 237), /* JTAG */
CNL_GPP(3, 238, 243), /* HVCMOS */
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 */
};
static const struct intel_community cnllp_communities[] = {
......
......@@ -131,10 +131,8 @@ struct chv_gpio_pinrange {
* @ngroups: Number of groups
* @functions: All functions in this community
* @nfunctions: Number of functions
* @ngpios: Number of GPIOs in this community
* @gpio_ranges: An array of GPIO ranges in this community
* @ngpio_ranges: Number of GPIO ranges
* @ngpios: Total number of GPIOs in this community
* @nirqs: Total number of IRQs this community can generate
*/
struct chv_community {
......@@ -147,7 +145,6 @@ struct chv_community {
size_t nfunctions;
const struct chv_gpio_pinrange *gpio_ranges;
size_t ngpio_ranges;
size_t ngpios;
size_t nirqs;
acpi_adr_space_type acpi_space_id;
};
......@@ -399,7 +396,6 @@ static const struct chv_community southwest_community = {
.nfunctions = ARRAY_SIZE(southwest_functions),
.gpio_ranges = southwest_gpio_ranges,
.ngpio_ranges = ARRAY_SIZE(southwest_gpio_ranges),
.ngpios = ARRAY_SIZE(southwest_pins),
/*
* Southwest community can benerate GPIO interrupts only for the
* first 8 interrupts. The upper half (8-15) can only be used to
......@@ -489,7 +485,6 @@ static const struct chv_community north_community = {
.npins = ARRAY_SIZE(north_pins),
.gpio_ranges = north_gpio_ranges,
.ngpio_ranges = ARRAY_SIZE(north_gpio_ranges),
.ngpios = ARRAY_SIZE(north_pins),
/*
* North community can generate GPIO interrupts only for the first
* 8 interrupts. The upper half (8-15) can only be used to trigger
......@@ -538,7 +533,6 @@ static const struct chv_community east_community = {
.npins = ARRAY_SIZE(east_pins),
.gpio_ranges = east_gpio_ranges,
.ngpio_ranges = ARRAY_SIZE(east_gpio_ranges),
.ngpios = ARRAY_SIZE(east_pins),
.nirqs = 16,
.acpi_space_id = 0x93,
};
......@@ -665,7 +659,6 @@ static const struct chv_community southeast_community = {
.nfunctions = ARRAY_SIZE(southeast_functions),
.gpio_ranges = southeast_gpio_ranges,
.ngpio_ranges = ARRAY_SIZE(southeast_gpio_ranges),
.ngpios = ARRAY_SIZE(southeast_pins),
.nirqs = 16,
.acpi_space_id = 0x94,
};
......@@ -1253,21 +1246,14 @@ static struct pinctrl_desc chv_pinctrl_desc = {
.owner = THIS_MODULE,
};
static unsigned chv_gpio_offset_to_pin(struct chv_pinctrl *pctrl,
unsigned offset)
{
return pctrl->community->pins[offset].number;
}
static int chv_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
int pin = chv_gpio_offset_to_pin(pctrl, offset);
unsigned long flags;
u32 ctrl0, cfg;
raw_spin_lock_irqsave(&chv_lock, flags);
ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
raw_spin_unlock_irqrestore(&chv_lock, flags);
cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
......@@ -1281,14 +1267,13 @@ static int chv_gpio_get(struct gpio_chip *chip, unsigned offset)
static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
unsigned pin = chv_gpio_offset_to_pin(pctrl, offset);
unsigned long flags;
void __iomem *reg;
u32 ctrl0;
raw_spin_lock_irqsave(&chv_lock, flags);
reg = chv_padreg(pctrl, pin, CHV_PADCTRL0);
reg = chv_padreg(pctrl, offset, CHV_PADCTRL0);
ctrl0 = readl(reg);
if (value)
......@@ -1304,12 +1289,11 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
{
struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
unsigned pin = chv_gpio_offset_to_pin(pctrl, offset);
u32 ctrl0, direction;
unsigned long flags;
raw_spin_lock_irqsave(&chv_lock, flags);
ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
raw_spin_unlock_irqrestore(&chv_lock, flags);
direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
......@@ -1345,7 +1329,7 @@ static void chv_gpio_irq_ack(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
int pin = chv_gpio_offset_to_pin(pctrl, irqd_to_hwirq(d));
int pin = irqd_to_hwirq(d);
u32 intr_line;
raw_spin_lock(&chv_lock);
......@@ -1362,7 +1346,7 @@ static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
int pin = chv_gpio_offset_to_pin(pctrl, irqd_to_hwirq(d));
int pin = irqd_to_hwirq(d);
u32 value, intr_line;
unsigned long flags;
......@@ -1407,8 +1391,7 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d)
if (irqd_get_trigger_type(d) == IRQ_TYPE_NONE) {
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
unsigned offset = irqd_to_hwirq(d);
int pin = chv_gpio_offset_to_pin(pctrl, offset);
unsigned pin = irqd_to_hwirq(d);
irq_flow_handler_t handler;
unsigned long flags;
u32 intsel, value;
......@@ -1426,7 +1409,7 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d)
if (!pctrl->intr_lines[intsel]) {
irq_set_handler_locked(d, handler);
pctrl->intr_lines[intsel] = offset;
pctrl->intr_lines[intsel] = pin;
}
raw_spin_unlock_irqrestore(&chv_lock, flags);
}
......@@ -1439,8 +1422,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned type)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
unsigned offset = irqd_to_hwirq(d);
int pin = chv_gpio_offset_to_pin(pctrl, offset);
unsigned pin = irqd_to_hwirq(d);
unsigned long flags;
u32 value;
......@@ -1486,7 +1468,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned type)
value &= CHV_PADCTRL0_INTSEL_MASK;
value >>= CHV_PADCTRL0_INTSEL_SHIFT;
pctrl->intr_lines[value] = offset;
pctrl->intr_lines[value] = pin;
if (type & IRQ_TYPE_EDGE_BOTH)
irq_set_handler_locked(d, handle_edge_irq);
......@@ -1576,12 +1558,12 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
const struct chv_gpio_pinrange *range;
struct gpio_chip *chip = &pctrl->chip;
bool need_valid_mask = !dmi_check_system(chv_no_valid_mask);
int ret, i, offset;
int irq_base;
const struct chv_community *community = pctrl->community;
int ret, i, irq_base;
*chip = chv_gpio_chip;
chip->ngpio = pctrl->community->ngpios;
chip->ngpio = community->pins[community->npins - 1].number + 1;
chip->label = dev_name(pctrl->dev);
chip->parent = pctrl->dev;
chip->base = -1;
......@@ -1593,30 +1575,29 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
return ret;
}
for (i = 0, offset = 0; i < pctrl->community->ngpio_ranges; i++) {
range = &pctrl->community->gpio_ranges[i];
ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev), offset,
range->base, range->npins);
for (i = 0; i < community->ngpio_ranges; i++) {
range = &community->gpio_ranges[i];
ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev),
range->base, range->base,
range->npins);
if (ret) {
dev_err(pctrl->dev, "failed to add GPIO pin range\n");
return ret;
}
offset += range->npins;
}
/* Do not add GPIOs that can only generate GPEs to the IRQ domain */
for (i = 0; i < pctrl->community->npins; i++) {
for (i = 0; i < community->npins; i++) {
const struct pinctrl_pin_desc *desc;
u32 intsel;
desc = &pctrl->community->pins[i];
desc = &community->pins[i];
intsel = readl(chv_padreg(pctrl, desc->number, CHV_PADCTRL0));
intsel &= CHV_PADCTRL0_INTSEL_MASK;
intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
if (need_valid_mask && intsel >= pctrl->community->nirqs)
if (need_valid_mask && intsel >= community->nirqs)
clear_bit(i, chip->irq.valid_mask);
}
......
......@@ -425,6 +425,18 @@ static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input)
writel(value, padcfg0);
}
static void intel_gpio_set_gpio_mode(void __iomem *padcfg0)
{
u32 value;
/* Put the pad into GPIO mode */
value = readl(padcfg0) & ~PADCFG0_PMODE_MASK;
/* Disable SCI/SMI/NMI generation */
value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI);
value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI);
writel(value, padcfg0);
}
static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned pin)
......@@ -432,7 +444,6 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
void __iomem *padcfg0;
unsigned long flags;
u32 value;
raw_spin_lock_irqsave(&pctrl->lock, flags);
......@@ -442,13 +453,7 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
}
padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
/* Put the pad into GPIO mode */
value = readl(padcfg0) & ~PADCFG0_PMODE_MASK;
/* Disable SCI/SMI/NMI generation */
value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI);
value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI);
writel(value, padcfg0);
intel_gpio_set_gpio_mode(padcfg0);
/* Disable TX buffer and enable RX (this will be input) */
__intel_gpio_set_direction(padcfg0, true);
......@@ -806,22 +811,63 @@ static const struct gpio_chip intel_gpio_chip = {
.set_config = gpiochip_generic_config,
};
/**
* intel_gpio_to_pin() - Translate from GPIO offset to pin number
* @pctrl: Pinctrl structure
* @offset: GPIO offset from gpiolib
* @commmunity: Community is filled here if not %NULL
* @padgrp: Pad group is filled here if not %NULL
*
* When coming through gpiolib irqchip, the GPIO offset is not
* automatically translated to pinctrl pin number. This function can be
* used to find out the corresponding pinctrl pin.
*/
static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned offset,
const struct intel_community **community,
const struct intel_padgroup **padgrp)
{
int i;
for (i = 0; i < pctrl->ncommunities; i++) {
const struct intel_community *comm = &pctrl->communities[i];
int j;
for (j = 0; j < comm->ngpps; j++) {
const struct intel_padgroup *pgrp = &comm->gpps[j];
if (pgrp->gpio_base < 0)
continue;
if (offset >= pgrp->gpio_base &&
offset < pgrp->gpio_base + pgrp->size) {
int pin;
pin = pgrp->base + offset - pgrp->gpio_base;
if (community)
*community = comm;
if (padgrp)
*padgrp = pgrp;
return pin;
}
}
}
return -EINVAL;
}
static void intel_gpio_irq_ack(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
const struct intel_community *community;
unsigned pin = irqd_to_hwirq(d);
const struct intel_padgroup *padgrp;
int pin;
community = intel_get_community(pctrl, pin);
if (community) {
const struct intel_padgroup *padgrp;
pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp);
if (pin >= 0) {
unsigned gpp, gpp_offset, is_offset;
padgrp = intel_community_get_padgroup(community, pin);
if (!padgrp)
return;
gpp = padgrp->reg_num;
gpp_offset = padgroup_offset(padgrp, pin);
is_offset = community->is_offset + gpp * 4;
......@@ -837,19 +883,15 @@ static void intel_gpio_irq_enable(struct irq_data *d)
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
const struct intel_community *community;
unsigned pin = irqd_to_hwirq(d);
const struct intel_padgroup *padgrp;
int pin;
community = intel_get_community(pctrl, pin);
if (community) {
const struct intel_padgroup *padgrp;
pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp);
if (pin >= 0) {
unsigned gpp, gpp_offset, is_offset;
unsigned long flags;
u32 value;
padgrp = intel_community_get_padgroup(community, pin);
if (!padgrp)
return;
gpp = padgrp->reg_num;
gpp_offset = padgroup_offset(padgrp, pin);
is_offset = community->is_offset + gpp * 4;
......@@ -870,20 +912,16 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
const struct intel_community *community;
unsigned pin = irqd_to_hwirq(d);
const struct intel_padgroup *padgrp;
int pin;
community = intel_get_community(pctrl, pin);
if (community) {
const struct intel_padgroup *padgrp;
pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp);
if (pin >= 0) {
unsigned gpp, gpp_offset;
unsigned long flags;
void __iomem *reg;
u32 value;
padgrp = intel_community_get_padgroup(community, pin);
if (!padgrp)
return;
gpp = padgrp->reg_num;
gpp_offset = padgroup_offset(padgrp, pin);
......@@ -914,7 +952,7 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
unsigned pin = irqd_to_hwirq(d);
unsigned pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
unsigned long flags;
void __iomem *reg;
u32 value;
......@@ -935,6 +973,8 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type)
raw_spin_lock_irqsave(&pctrl->lock, flags);
intel_gpio_set_gpio_mode(reg);
value = readl(reg);
value &= ~(PADCFG0_RXEVCFG_MASK | PADCFG0_RXINV);
......@@ -969,7 +1009,7 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
unsigned pin = irqd_to_hwirq(d);
unsigned pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
if (on)
enable_irq_wake(pctrl->irq);
......@@ -1000,14 +1040,10 @@ static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl,
pending &= enabled;
for_each_set_bit(gpp_offset, &pending, padgrp->size) {
unsigned padno, irq;
padno = padgrp->base - community->pin_base + gpp_offset;
if (padno >= community->npins)
break;
unsigned irq;
irq = irq_find_mapping(gc->irq.domain,
community->pin_base + padno);
padgrp->gpio_base + gpp_offset);
generic_handle_irq(irq);
ret |= IRQ_HANDLED;
......@@ -1044,13 +1080,56 @@ static struct irq_chip intel_gpio_irqchip = {
.flags = IRQCHIP_MASK_ON_SUSPEND,
};
static int intel_gpio_add_pin_ranges(struct intel_pinctrl *pctrl,
const struct intel_community *community)
{
int ret = 0, i;
for (i = 0; i < community->ngpps; i++) {
const struct intel_padgroup *gpp = &community->gpps[i];
if (gpp->gpio_base < 0)
continue;
ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
gpp->gpio_base, gpp->base,
gpp->size);
if (ret)
return ret;
}
return ret;
}
static unsigned intel_gpio_ngpio(const struct intel_pinctrl *pctrl)
{
const struct intel_community *community;
unsigned ngpio = 0;
int i, j;
for (i = 0; i < pctrl->ncommunities; i++) {
community = &pctrl->communities[i];
for (j = 0; j < community->ngpps; j++) {
const struct intel_padgroup *gpp = &community->gpps[j];
if (gpp->gpio_base < 0)
continue;
if (gpp->gpio_base + gpp->size > ngpio)
ngpio = gpp->gpio_base + gpp->size;
}
}
return ngpio;
}
static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
{
int ret;
int ret, i;
pctrl->chip = intel_gpio_chip;
pctrl->chip.ngpio = pctrl->soc->npins;
pctrl->chip.ngpio = intel_gpio_ngpio(pctrl);
pctrl->chip.label = dev_name(pctrl->dev);
pctrl->chip.parent = pctrl->dev;
pctrl->chip.base = -1;
......@@ -1062,11 +1141,14 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
return ret;
}
ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
0, 0, pctrl->soc->npins);
if (ret) {
dev_err(pctrl->dev, "failed to add GPIO pin range\n");
return ret;
for (i = 0; i < pctrl->ncommunities; i++) {
struct intel_community *community = &pctrl->communities[i];
ret = intel_gpio_add_pin_ranges(pctrl, community);
if (ret) {
dev_err(pctrl->dev, "failed to add GPIO pin range\n");
return ret;
}
}
/*
......@@ -1126,6 +1208,9 @@ 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;
gpps[i].padown_num = padown_num;
/*
......
......@@ -51,6 +51,8 @@ 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)
* @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
......@@ -60,6 +62,7 @@ struct intel_padgroup {
unsigned reg_num;
unsigned base;
unsigned size;
int gpio_base;
unsigned padown_num;
};
......
......@@ -931,10 +931,17 @@ static int mrfld_pinctrl_probe(struct platform_device *pdev)
return 0;
}
static const struct acpi_device_id mrfld_acpi_table[] = {
{ "INTC1002" },
{ }
};
MODULE_DEVICE_TABLE(acpi, mrfld_acpi_table);
static struct platform_driver mrfld_pinctrl_driver = {
.probe = mrfld_pinctrl_probe,
.driver = {
.name = "pinctrl-merrifield",
.acpi_match_table = mrfld_acpi_table,
},
};
......
if ARCH_MEDIATEK || COMPILE_TEST
menu "MediaTek pinctrl drivers"
depends on ARCH_MEDIATEK || COMPILE_TEST
config PINCTRL_MTK
bool
......@@ -31,6 +32,16 @@ config PINCTRL_MT8127
select PINCTRL_MTK
# For ARMv8 SoCs
config PINCTRL_MT7622
bool "MediaTek MT7622 pin control"
depends on OF
depends on ARM64 || COMPILE_TEST
select GENERIC_PINCONF
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
select GPIOLIB
select OF_GPIO
config PINCTRL_MT8173
bool "Mediatek MT8173 pin control"
depends on OF
......@@ -46,4 +57,4 @@ config PINCTRL_MT6397
default MFD_MT6397
select PINCTRL_MTK
endif
endmenu
# SPDX-License-Identifier: GPL-2.0
# Core
obj-y += pinctrl-mtk-common.o
obj-$(CONFIG_PINCTRL_MTK) += pinctrl-mtk-common.o
# SoC Drivers
obj-$(CONFIG_PINCTRL_MT2701) += pinctrl-mt2701.o
obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o
obj-$(CONFIG_PINCTRL_MT8127) += pinctrl-mt8127.o
obj-$(CONFIG_PINCTRL_MT7622) += pinctrl-mt7622.o
obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
obj-$(CONFIG_PINCTRL_MT6397) += pinctrl-mt6397.o
This diff is collapsed.
......@@ -38,4 +38,13 @@ config PINCTRL_MESON_GXL
config PINCTRL_MESON8_PMX
bool
config PINCTRL_MESON_AXG
bool "Meson axg Soc pinctrl driver"
depends on ARM64
select PINCTRL_MESON_AXG_PMX
default y
config PINCTRL_MESON_AXG_PMX
bool
endif
......@@ -4,3 +4,5 @@ obj-$(CONFIG_PINCTRL_MESON8) += pinctrl-meson8.o
obj-$(CONFIG_PINCTRL_MESON8B) += pinctrl-meson8b.o
obj-$(CONFIG_PINCTRL_MESON_GXBB) += pinctrl-meson-gxbb.o
obj-$(CONFIG_PINCTRL_MESON_GXL) += pinctrl-meson-gxl.o
obj-$(CONFIG_PINCTRL_MESON_AXG_PMX) += pinctrl-meson-axg-pmx.o
obj-$(CONFIG_PINCTRL_MESON_AXG) += pinctrl-meson-axg.o
/*
* Second generation of pinmux driver for Amlogic Meson-AXG SoC.
*
* Copyright (c) 2017 Baylibre SAS.
* Author: Jerome Brunet <jbrunet@baylibre.com>
*
* Copyright (c) 2017 Amlogic, Inc. All rights reserved.
* Author: Xingyu Chen <xingyu.chen@amlogic.com>
*
* SPDX-License-Identifier: (GPL-2.0+ or MIT)
*/
/*
* This new generation of pinctrl IP is mainly adopted by the
* Meson-AXG SoC and later series, which use 4-width continuous
* register bit to select the function for each pin.
*
* The value 0 is always selecting the GPIO mode, while other
* values (start from 1) for selecting the function mode.
*/
#include <linux/device.h>
#include <linux/regmap.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include "pinctrl-meson.h"
#include "pinctrl-meson-axg-pmx.h"
static int meson_axg_pmx_get_bank(struct meson_pinctrl *pc,
unsigned int pin,
struct meson_pmx_bank **bank)
{
int i;
struct meson_axg_pmx_data *pmx = pc->data->pmx_data;
for (i = 0; i < pmx->num_pmx_banks; i++)
if (pin >= pmx->pmx_banks[i].first &&
pin <= pmx->pmx_banks[i].last) {
*bank = &pmx->pmx_banks[i];
return 0;
}
return -EINVAL;
}
static int meson_pmx_calc_reg_and_offset(struct meson_pmx_bank *bank,
unsigned int pin, unsigned int *reg,
unsigned int *offset)
{
int shift;
shift = pin - bank->first;
*reg = bank->reg + (bank->offset + (shift << 2)) / 32;
*offset = (bank->offset + (shift << 2)) % 32;
return 0;
}
static int meson_axg_pmx_update_function(struct meson_pinctrl *pc,
unsigned int pin, unsigned int func)
{
int ret;
int reg;
int offset;
struct meson_pmx_bank *bank;
ret = meson_axg_pmx_get_bank(pc, pin, &bank);
if (ret)
return ret;
meson_pmx_calc_reg_and_offset(bank, pin, &reg, &offset);
ret = regmap_update_bits(pc->reg_mux, reg << 2,
0xf << offset, (func & 0xf) << offset);
return ret;
}
static int meson_axg_pmx_set_mux(struct pinctrl_dev *pcdev,
unsigned int func_num, unsigned int group_num)
{
int i;
int ret;
struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
struct meson_pmx_func *func = &pc->data->funcs[func_num];
struct meson_pmx_group *group = &pc->data->groups[group_num];
struct meson_pmx_axg_data *pmx_data =
(struct meson_pmx_axg_data *)group->data;
dev_dbg(pc->dev, "enable function %s, group %s\n", func->name,
group->name);
for (i = 0; i < group->num_pins; i++) {
ret = meson_axg_pmx_update_function(pc, group->pins[i],
pmx_data->func);
if (ret)
return ret;
}
return 0;
}
static int meson_axg_pmx_request_gpio(struct pinctrl_dev *pcdev,
struct pinctrl_gpio_range *range, unsigned int offset)
{
struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
return meson_axg_pmx_update_function(pc, offset, 0);
}
const struct pinmux_ops meson_axg_pmx_ops = {
.set_mux = meson_axg_pmx_set_mux,
.get_functions_count = meson_pmx_get_funcs_count,
.get_function_name = meson_pmx_get_func_name,
.get_function_groups = meson_pmx_get_groups,
.gpio_request_enable = meson_axg_pmx_request_gpio,
};
/*
* Copyright (c) 2017 Baylibre SAS.
* Author: Jerome Brunet <jbrunet@baylibre.com>
*
* Copyright (c) 2017 Amlogic, Inc. All rights reserved.
* Author: Xingyu Chen <xingyu.chen@amlogic.com>
*
* SPDX-License-Identifier: (GPL-2.0+ or MIT)
*/
struct meson_pmx_bank {
const char *name;
unsigned int first;
unsigned int last;
unsigned int reg;
unsigned int offset;
};
struct meson_axg_pmx_data {
struct meson_pmx_bank *pmx_banks;
unsigned int num_pmx_banks;
};
#define BANK_PMX(n, f, l, r, o) \
{ \
.name = n, \
.first = f, \
.last = l, \
.reg = r, \
.offset = o, \
}
struct meson_pmx_axg_data {
unsigned int func;
};
#define PMX_DATA(f) \
{ \
.func = f, \
}
#define GROUP(grp, f) \
{ \
.name = #grp, \
.pins = grp ## _pins, \
.num_pins = ARRAY_SIZE(grp ## _pins), \
.data = (const struct meson_pmx_axg_data[]){ \
PMX_DATA(f), \
}, \
}
#define GPIO_GROUP(gpio) \
{ \
.name = #gpio, \
.pins = (const unsigned int[]){ gpio }, \
.num_pins = 1, \
.data = (const struct meson_pmx_axg_data[]){ \
PMX_DATA(0), \
}, \
}
extern const struct pinmux_ops meson_axg_pmx_ops;
This diff is collapsed.
......@@ -108,6 +108,7 @@ struct meson_pinctrl_data {
struct meson_bank *banks;
unsigned int num_banks;
const struct pinmux_ops *pmx_ops;
void *pmx_data;
};
struct meson_pinctrl {
......
......@@ -1006,11 +1006,11 @@ static int armada_37xx_pinctrl_register(struct platform_device *pdev,
static const struct of_device_id armada_37xx_pinctrl_of_match[] = {
{
.compatible = "marvell,armada3710-sb-pinctrl",
.data = (void *)&armada_37xx_pin_sb,
.data = &armada_37xx_pin_sb,
},
{
.compatible = "marvell,armada3710-nb-pinctrl",
.data = (void *)&armada_37xx_pin_nb,
.data = &armada_37xx_pin_nb,
},
{ },
};
......
......@@ -636,10 +636,9 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
*/
size = pctl->num_groups * sizeof(*pctl->groups) + noname * 8;
p = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
if (!p) {
dev_err(&pdev->dev, "failed to alloc group data\n");
if (!p)
return -ENOMEM;
}
pctl->groups = p;
noname_buf = p + pctl->num_groups * sizeof(*pctl->groups);
......
......@@ -633,7 +633,7 @@ static void abx500_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
for (i = 0; i < chip->ngpio; i++, gpio++) {
/* On AB8500, there is no GPIO0, the first is the GPIO 1 */
abx500_gpio_dbg_show_one(s, pctldev, chip, i + 1, gpio);
seq_printf(s, "\n");
seq_putc(s, '\n');
}
}
......@@ -1155,13 +1155,9 @@ static int abx500_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
pct = devm_kzalloc(&pdev->dev, sizeof(struct abx500_pinctrl),
GFP_KERNEL);
if (pct == NULL) {
dev_err(&pdev->dev,
"failed to allocate memory for pct\n");
pct = devm_kzalloc(&pdev->dev, sizeof(*pct), GFP_KERNEL);
if (!pct)
return -ENOMEM;
}
pct->dev = &pdev->dev;
pct->parent = dev_get_drvdata(pdev->dev.parent);
......
......@@ -827,13 +827,10 @@ static int adi_gpio_pint_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct resource *res;
struct gpio_pint *pint;
struct gpio_pint *pint = devm_kzalloc(dev, sizeof(*pint), GFP_KERNEL);
pint = devm_kzalloc(dev, sizeof(struct gpio_pint), GFP_KERNEL);
if (!pint) {
dev_err(dev, "Memory alloc failed\n");
if (!pint)
return -ENOMEM;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pint->base = devm_ioremap_resource(dev, res);
......@@ -945,11 +942,9 @@ static int adi_gpio_probe(struct platform_device *pdev)
if (!pdata)
return -EINVAL;
port = devm_kzalloc(dev, sizeof(struct gpio_port), GFP_KERNEL);
if (!port) {
dev_err(dev, "Memory alloc failed\n");
port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
if (!port)
return -ENOMEM;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
port->base = devm_ioremap_resource(dev, res);
......
......@@ -910,7 +910,7 @@ static int atmel_pinctrl_probe(struct platform_device *pdev)
int i, ret;
struct resource *res;
struct atmel_pioctrl *atmel_pioctrl;
struct atmel_pioctrl_data *atmel_pioctrl_data;
const struct atmel_pioctrl_data *atmel_pioctrl_data;
atmel_pioctrl = devm_kzalloc(dev, sizeof(*atmel_pioctrl), GFP_KERNEL);
if (!atmel_pioctrl)
......@@ -924,7 +924,7 @@ static int atmel_pinctrl_probe(struct platform_device *pdev)
dev_err(dev, "unknown compatible string\n");
return -ENODEV;
}
atmel_pioctrl_data = (struct atmel_pioctrl_data *)match->data;
atmel_pioctrl_data = match->data;
atmel_pioctrl->nbanks = atmel_pioctrl_data->nbanks;
atmel_pioctrl->npins = atmel_pioctrl->nbanks * ATMEL_PIO_NPINS_PER_BANK;
......
......@@ -1050,10 +1050,8 @@ static int at91_pinctrl_mux_mask(struct at91_pinctrl *info,
info->nmux = size / gpio_banks;
info->mux_mask = devm_kzalloc(info->dev, sizeof(u32) * size, GFP_KERNEL);
if (!info->mux_mask) {
dev_err(info->dev, "could not alloc mux_mask\n");
if (!info->mux_mask)
return -ENOMEM;
}
ret = of_property_read_u32_array(np, "atmel,mux-mask",
info->mux_mask, size);
......
......@@ -413,9 +413,11 @@ static int axp20x_pctl_probe(struct platform_device *pdev)
pctl->chip.set = axp20x_gpio_set;
pctl->chip.direction_input = axp20x_gpio_input;
pctl->chip.direction_output = axp20x_gpio_output;
pctl->desc = of_device_get_match_data(dev);
pctl->chip.ngpio = pctl->desc->npins;
pctl->desc = (struct axp20x_pctrl_desc *)of_device_get_match_data(dev);
pctl->regmap = axp20x->regmap;
pctl->dev = &pdev->dev;
......
This diff is collapsed.
......@@ -736,10 +736,8 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev)
base = devm_ioremap_resource(dev,
platform_get_resource(pdev, IORESOURCE_MEM, 0));
if (IS_ERR(base)) {
dev_err(dev, "Failed to ioremap registers\n");
if (IS_ERR(base))
return PTR_ERR(base);
}
jzpc->map = devm_regmap_init_mmio(dev, base,
&ingenic_pinctrl_regmap_config);
......
This diff is collapsed.
This diff is collapsed.
......@@ -1012,10 +1012,8 @@ static int palmas_pinctrl_probe(struct platform_device *pdev)
}
pci = devm_kzalloc(&pdev->dev, sizeof(*pci), GFP_KERNEL);
if (!pci) {
dev_err(&pdev->dev, "Malloc for pci failed\n");
if (!pci)
return -ENOMEM;
}
pci->dev = &pdev->dev;
pci->palmas = dev_get_drvdata(pdev->dev.parent);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -357,10 +357,8 @@ static int add_map_configs(struct device *dev,
dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
GFP_KERNEL);
if (!dup_configs) {
dev_err(dev, "kmemdup(configs) failed\n");
if (!dup_configs)
return -ENOMEM;
}
/*
* We support both pins and pin groups, but we need to figure out which
......@@ -931,10 +929,9 @@ static int tz1090_pdc_pinctrl_probe(struct platform_device *pdev)
struct resource *res;
pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
if (!pmx) {
dev_err(&pdev->dev, "Can't alloc tz1090_pdc_pmx\n");
if (!pmx)
return -ENOMEM;
}
pmx->dev = &pdev->dev;
spin_lock_init(&pmx->lock);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment