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

Merge tag 'pinctrl-v4.15-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.15 kernel cycle:

  Core:

   - The pin control Kconfig entry PINCTRL is now turned into a
     menuconfig option. This obviously has the implication of making the
     subsystem menu visible in menuconfig. This is happening because of
     two things:

      (a) Intel have started to deploy and depend on pin controllers in
          a way that is affecting users directly. This happens on the
          highly integrated laptop chipsets named after geographical
          places: baytrail, broxton, cannonlake, cedarfork, cherryview,
          denverton, geminilake, lewisburg, merrifield, sunrisepoint...
          It started a while back and now it is ever more evident that
          this is crucial infrastructure for x86 laptops and not an
          embedded obscurity anymore. Users need to be aware.

      (b) Pin control expanders on I2C and SPI that are arch-agnostic.
          Currently Semtech SX150X and Microchip MCP28x08 but more are
          expected. Users will have to be able to configure these in
          directly for their set-up.

   - Just go and select GPIOLIB now that we made sure that GPIOLIB is a
     very vanilla subsystem. Do not depend on it, if we need it, select
     it.

   - Exposing the pin control subsystem in menuconfig uncovered a bunch
     of obscure bugs that are now hopefully fixed, all more or less
     pertaining to Blackfin.

   - Unified namespace for cross-calls between pin control and GPIO.

   - New support for clock skew/delay generic DT bindings and generic
     pin config options for this.

   - Minor documentation improvements.

  Various:

   - The Renesas SH-PFC pin controller has evolved a lot. It seems
     Renesas are churning out new SoCs by the minute.

   - A bunch of non-critical fixes for the Rockchip driver.

   - Improve the use of library functions instead of open coding.

   - Support the MCP28018 variant in the MCP28x08 driver.

   - Static constifying"

* tag 'pinctrl-v4.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (91 commits)
  pinctrl: gemini: Fix missing pad descriptions
  pinctrl: Add some depends on HAS_IOMEM
  pinctrl: samsung/s3c24xx: add CONFIG_OF dependency
  pinctrl: gemini: Fix GMAC groups
  pinctrl: qcom: spmi-gpio: Add pmi8994 gpio support
  pinctrl: ti-iodelay: remove redundant unused variable dev
  pinctrl: max77620: Use common error handling code in max77620_pinconf_set()
  pinctrl: gemini: Implement clock skew/delay config
  pinctrl: gemini: Use generic DT parser
  pinctrl: Add skew-delay pin config and bindings
  pinctrl: armada-37xx: Add edge both type gpio irq support
  pinctrl: uniphier: remove eMMC hardware reset pin-mux
  pinctrl: rockchip: Add iomux-route switching support for rk3288
  pinctrl: intel: Add Intel Cedar Fork PCH pin controller support
  pinctrl: intel: Make offset to interrupt status register configurable
  pinctrl: sunxi: Enforce the strict mode by default
  pinctrl: sunxi: Disable strict mode for old pinctrl drivers
  pinctrl: sunxi: Introduce the strict flag
  pinctrl: sh-pfc: Save/restore registers for PSCI system suspend
  pinctrl: sh-pfc: r8a7796: Use generic IOCTRL register description
  ...
......@@ -9,8 +9,14 @@ The pin controller node must be a subnode of the system controller node.
Required properties:
- compatible: "cortina,gemini-pinctrl"
Subnodes of the pin controller contain pin control multiplexing set-up.
Please refer to pinctrl-bindings.txt for generic pin multiplexing nodes.
Subnodes of the pin controller contain pin control multiplexing set-up
and pin configuration of individual pins.
Please refer to pinctrl-bindings.txt for generic pin multiplexing nodes
and generic pin config nodes.
Supported configurations:
- skew-delay is supported on the Ethernet pins
Example:
......
......@@ -97,8 +97,8 @@ group spi_quad
- pins 15-16
- functions spi, gpio
group uart_2
- pins 9-10
group uart2
- pins 9-10 and 18-19
- functions uart, gpio
Available groups and functions for the South bridge:
......
......@@ -271,6 +271,10 @@ output-high - set the pin to output mode with high level
sleep-hardware-state - indicate this is sleep related state which will be programmed
into the registers for the sleep state.
slew-rate - set the slew rate
skew-delay - this affects the expected clock skew on input pins
and the delay before latching a value to an output
pin. Typically indicates how many double-inverters are
used to delay the signal.
For example:
......
......@@ -13,6 +13,7 @@ Required properties:
- "microchip,mcp23s18" for 16 GPIO SPI version
- "microchip,mcp23008" for 8 GPIO I2C version or
- "microchip,mcp23017" for 16 GPIO I2C version of the chip
- "microchip,mcp23018" for 16 GPIO I2C version
NOTE: Do not use the old mcp prefix any more. It is deprecated and will be
removed.
- #gpio-cells : Should be two.
......@@ -81,3 +82,61 @@ gpiom1: gpio@0 {
reg = <0>;
spi-max-frequency = <1000000>;
};
Pull-up configuration
=====================
If pins are used as output, they can also be configured with pull-ups. This is
done with pinctrl.
Please refer file <devicetree/bindings/pinctrl/pinctrl-bindings.txt>
for details of the common pinctrl bindings used by client devices,
including the meaning of the phrase "pin configuration node".
Optional Pinmux properties:
--------------------------
Following properties are required if default setting of pins are required
at boot.
- pinctrl-names: A pinctrl state named per <pinctrl-binding.txt>.
- pinctrl[0...n]: Properties to contain the phandle for pinctrl states per
<pinctrl-binding.txt>.
The pin configurations are defined as child of the pinctrl states node. Each
sub-node have following properties:
Required properties:
------------------
- pins: List of pins. Valid values of pins properties are:
gpio0 ... gpio7 for the devices with 8 GPIO pins and
gpio0 ... gpio15 for the devices with 16 GPIO pins.
Optional properties:
-------------------
The following optional property is defined in the pinmux DT binding document
<pinctrl-bindings.txt>. Absence of this property will leave the configuration
in its default state.
bias-pull-up
Example with pinctrl to pull-up output pins:
gpio21: gpio@21 {
compatible = "microchip,mcp23017";
gpio-controller;
#gpio-cells = <0x2>;
reg = <0x21>;
interrupt-parent = <&socgpio>;
interrupts = <0x17 0x8>;
interrupt-names = "mcp23017@21 irq";
interrupt-controller;
#interrupt-cells = <0x2>;
microchip,irq-mirror;
pinctrl-names = "default";
pinctrl-0 = <&i2cgpio0irq &gpio21pullups>;
gpio21pullups: pinmux {
pins = "gpio0", "gpio1", "gpio2", "gpio3",
"gpio4", "gpio5", "gpio6", "gpio7",
"gpio8", "gpio9", "gpio10", "gpio11",
"gpio12", "gpio13", "gpio14", "gpio15";
bias-pull-up;
};
};
......@@ -15,6 +15,7 @@ PMIC's from Qualcomm.
"qcom,pm8921-gpio"
"qcom,pm8941-gpio"
"qcom,pm8994-gpio"
"qcom,pmi8994-gpio"
"qcom,pma8084-gpio"
"qcom,pmi8994-gpio"
......@@ -85,6 +86,7 @@ to specify in a pin configuration subnode:
gpio1-gpio44 for pm8921
gpio1-gpio36 for pm8941
gpio1-gpio22 for pm8994
gpio1-gpio10 for pmi8994
gpio1-gpio22 for pma8084
gpio1-gpio10 for pmi8994
......
......@@ -12,8 +12,10 @@ Pin controller node
-------------------
Required properties:
- compatible
this shall be "renesas,r7s72100-ports".
- compatible: should be:
- "renesas,r7s72100-ports": for RZ/A1H
- "renesas,r7s72101-ports", "renesas,r7s72100-ports": for RZ/A1M
- "renesas,r7s72102-ports": for RZ/A1L
- reg
address base and length of the memory area where the pin controller
......
......@@ -757,8 +757,8 @@ that your datasheet calls "GPIO mode", but actually is just an electrical
configuration for a certain device. See the section below named
"GPIO mode pitfalls" for more details on this scenario.
The public pinmux API contains two functions named pinctrl_request_gpio()
and pinctrl_free_gpio(). These two functions shall *ONLY* be called from
The public pinmux API contains two functions named pinctrl_gpio_request()
and pinctrl_gpio_free(). These two functions shall *ONLY* be called from
gpiolib-based drivers as part of their gpio_request() and
gpio_free() semantics. Likewise the pinctrl_gpio_direction_[input|output]
shall only be called from within respective gpio_direction_[input|output]
......@@ -790,7 +790,7 @@ gpiolib driver and the affected GPIO range, pin offset and desired direction
will be passed along to this function.
Alternatively to using these special functions, it is fully allowed to use
named functions for each GPIO pin, the pinctrl_request_gpio() will attempt to
named functions for each GPIO pin, the pinctrl_gpio_request() will attempt to
obtain the function "gpioN" where "N" is the global GPIO pin number if no
special GPIO-handler is registered.
......
......@@ -273,8 +273,8 @@ easily, gating off unused clocks.
For GPIOs that use pins known to the pinctrl subsystem, that subsystem should
be informed of their use; a gpiolib driver's .request() operation may call
pinctrl_request_gpio(), and a gpiolib driver's .free() operation may call
pinctrl_free_gpio(). The pinctrl subsystem allows a pinctrl_request_gpio()
pinctrl_gpio_request(), and a gpiolib driver's .free() operation may call
pinctrl_gpio_free(). The pinctrl subsystem allows a pinctrl_gpio_request()
to succeed concurrently with a pin or pingroup being "owned" by a device for
pin multiplexing.
......@@ -448,8 +448,8 @@ together with an optional gpio feature. We have already covered the
case where e.g. a GPIO controller need to reserve a pin or set the
direction of a pin by calling any of:
pinctrl_request_gpio()
pinctrl_free_gpio()
pinctrl_gpio_request()
pinctrl_gpio_free()
pinctrl_gpio_direction_input()
pinctrl_gpio_direction_output()
......@@ -466,7 +466,7 @@ gpio (under gpiolib) is still maintained by gpio drivers. It may happen
that different pin ranges in a SoC is managed by different gpio drivers.
This makes it logical to let gpio drivers announce their pin ranges to
the pin ctrl subsystem before it will call 'pinctrl_request_gpio' in order
the pin ctrl subsystem before it will call 'pinctrl_gpio_request' in order
to request the corresponding pin to be prepared by the pinctrl subsystem
before any gpio usage.
......
......@@ -257,9 +257,9 @@ GPIO 值的命令需要等待其信息排到队首才发送命令,再获得其
简单地关闭未使用时钟)。
对于 GPIO 使用 pinctrl 子系统已知的引脚,子系统应该被告知其使用情况;
一个 gpiolib 驱动的 .request()操作应调用 pinctrl_request_gpio(),
而 gpiolib 驱动的 .free()操作应调用 pinctrl_free_gpio()。pinctrl
子系统允许 pinctrl_request_gpio()在某个引脚或引脚组以复用形式“属于”
一个 gpiolib 驱动的 .request()操作应调用 pinctrl_gpio_request(),
而 gpiolib 驱动的 .free()操作应调用 pinctrl_gpio_free()。pinctrl
子系统允许 pinctrl_gpio_request()在某个引脚或引脚组以复用形式“属于”
一个设备时都成功返回。
任何须将 GPIO 信号导向适当引脚的引脚复用硬件的编程应该发生在 GPIO
......
......@@ -10713,6 +10713,7 @@ PIN CONTROLLER - RENESAS
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
M: Geert Uytterhoeven <geert+renesas@glider.be>
L: linux-renesas-soc@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git sh-pfc
S: Maintained
F: drivers/pinctrl/sh-pfc/
......
......@@ -321,11 +321,14 @@ config BF53x
config GPIO_ADI
def_bool y
depends on !PINCTRL
depends on (BF51x || BF52x || BF53x || BF538 || BF539 || BF561)
config PINCTRL
config PINCTRL_BLACKFIN_ADI2
def_bool y
depends on BF54x || BF60x
depends on (BF54x || BF60x)
select PINCTRL
select PINCTRL_ADI2
config MEM_MT48LC64M4A2FB_7E
bool
......
......@@ -18,6 +18,7 @@ config DEBUG_VERBOSE
config DEBUG_MMRS
tristate "Generate Blackfin MMR tree"
depends on !PINCTRL
select DEBUG_FS
help
Create a tree of Blackfin MMRs via the debugfs tree. If
......
......@@ -183,6 +183,26 @@ static inline int irq_to_gpio(unsigned irq)
{
return irq - GPIO_IRQ_BASE;
}
#else /* CONFIG_PINCTRL */
/*
* CONFIG_PM is not working with pin control and should probably
* avoid being selected when pin control is active, but so far,
* these stubs are here to make allyesconfig and allmodconfig
* compile properly. These functions are normally backed by the
* CONFIG_ADI_GPIO custom GPIO implementation.
*/
static inline int bfin_pm_standby_setup(void)
{
return 0;
}
static inline void bfin_pm_standby_restore(void)
{
}
#endif /* CONFIG_PINCTRL */
#include <asm/irq.h>
......
......@@ -15,6 +15,9 @@
/* FIXME: consumer API required for gpio_set_value() etc, get rid of this */
#include <linux/gpio.h>
#include <linux/irq.h>
#include <asm/gpio.h>
#include <asm/irq_handler.h>
#include <asm/portmux.h>
#if ANOMALY_05000311 || ANOMALY_05000323
enum {
......
......@@ -10,7 +10,6 @@
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <asm/blackfin.h>
#include <asm/gptimers.h>
......@@ -20,6 +19,7 @@
#include <asm/bfin_serial.h>
#include <asm/bfin5xx_spi.h>
#include <asm/bfin_twi.h>
#include <asm/gpio.h>
/* Common code defines PORT_MUX on us, so redirect the MMR back locally */
#ifdef BFIN_PORT_MUX
......
......@@ -18,7 +18,6 @@
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/syscore_ops.h>
#include <linux/gpio.h>
#include <asm/delay.h>
#ifdef CONFIG_IPIPE
#include <linux/ipipe.h>
......@@ -28,6 +27,7 @@
#include <asm/irq_handler.h>
#include <asm/dpmc.h>
#include <asm/traps.h>
#include <asm/gpio.h>
/*
* NOTES:
......
......@@ -15,12 +15,12 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <asm/cplb.h>
#include <asm/dma.h>
#include <asm/dpmc.h>
#include <asm/pm.h>
#include <asm/gpio.h>
#ifdef CONFIG_BF60x
struct bfin_cpu_pm_fns *bfin_cpu_pm;
......
......@@ -834,15 +834,6 @@ config GPIO_PCF857X
This driver provides an in-kernel interface to those GPIOs using
platform-neutral GPIO calls.
config GPIO_SX150X
bool "Semtech SX150x I2C GPIO expander (deprecated)"
depends on PINCTRL && I2C=y
select PINCTRL_SX150X
default n
help
Say yes here to provide support for Semtech SX150x-series I2C
GPIO expanders. The GPIO driver was replaced by a Pinctrl version.
config GPIO_TPIC2810
tristate "TPIC2810 8-Bit I2C GPO expander"
help
......
......@@ -539,12 +539,12 @@ static int aspeed_gpio_request(struct gpio_chip *chip, unsigned int offset)
if (!have_gpio(gpiochip_get_data(chip), offset))
return -ENODEV;
return pinctrl_request_gpio(chip->base + offset);
return pinctrl_gpio_request(chip->base + offset);
}
static void aspeed_gpio_free(struct gpio_chip *chip, unsigned int offset)
{
pinctrl_free_gpio(chip->base + offset);
pinctrl_gpio_free(chip->base + offset);
}
static inline void __iomem *bank_debounce_reg(struct aspeed_gpio *gpio,
......
......@@ -239,12 +239,12 @@ static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset)
static int em_gio_request(struct gpio_chip *chip, unsigned offset)
{
return pinctrl_request_gpio(chip->base + offset);
return pinctrl_gpio_request(chip->base + offset);
}
static void em_gio_free(struct gpio_chip *chip, unsigned offset)
{
pinctrl_free_gpio(chip->base + offset);
pinctrl_gpio_free(chip->base + offset);
/* Set the GPIO as an input to ensure that the next GPIO request won't
* drive the GPIO pin as an output.
......
......@@ -330,16 +330,6 @@ static int pxa_gpio_of_xlate(struct gpio_chip *gc,
}
#endif
static int pxa_gpio_request(struct gpio_chip *chip, unsigned int offset)
{
return pinctrl_request_gpio(chip->base + offset);
}
static void pxa_gpio_free(struct gpio_chip *chip, unsigned int offset)
{
pinctrl_free_gpio(chip->base + offset);
}
static int pxa_init_gpio_chip(struct pxa_gpio_chip *pchip, int ngpio,
struct device_node *np, void __iomem *regbase)
{
......@@ -358,8 +348,8 @@ static int pxa_init_gpio_chip(struct pxa_gpio_chip *pchip, int ngpio,
pchip->chip.set = pxa_gpio_set;
pchip->chip.to_irq = pxa_gpio_to_irq;
pchip->chip.ngpio = ngpio;
pchip->chip.request = pxa_gpio_request;
pchip->chip.free = pxa_gpio_free;
pchip->chip.request = gpiochip_generic_request;
pchip->chip.free = gpiochip_generic_free;
#ifdef CONFIG_OF_GPIO
pchip->chip.of_node = np;
pchip->chip.of_xlate = pxa_gpio_of_xlate;
......
......@@ -250,7 +250,7 @@ static int gpio_rcar_request(struct gpio_chip *chip, unsigned offset)
if (error < 0)
return error;
error = pinctrl_request_gpio(chip->base + offset);
error = pinctrl_gpio_request(chip->base + offset);
if (error)
pm_runtime_put(&p->pdev->dev);
......@@ -261,7 +261,7 @@ static void gpio_rcar_free(struct gpio_chip *chip, unsigned offset)
{
struct gpio_rcar_priv *p = gpiochip_get_data(chip);
pinctrl_free_gpio(chip->base + offset);
pinctrl_gpio_free(chip->base + offset);
/*
* Set the GPIO as an input to ensure that the next GPIO request won't
......
......@@ -141,14 +141,14 @@ static void tegra_gpio_disable(struct tegra_gpio_info *tgi, unsigned int gpio)
static int tegra_gpio_request(struct gpio_chip *chip, unsigned int offset)
{
return pinctrl_request_gpio(offset);
return pinctrl_gpio_request(offset);
}
static void tegra_gpio_free(struct gpio_chip *chip, unsigned int offset)
{
struct tegra_gpio_info *tgi = gpiochip_get_data(chip);
pinctrl_free_gpio(offset);
pinctrl_gpio_free(offset);
tegra_gpio_disable(tgi, offset);
}
......
......@@ -232,7 +232,7 @@ static int tz1090_gpio_request(struct gpio_chip *chip, unsigned int offset)
struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
int ret;
ret = pinctrl_request_gpio(chip->base + offset);
ret = pinctrl_gpio_request(chip->base + offset);
if (ret)
return ret;
......@@ -246,7 +246,7 @@ static void tz1090_gpio_free(struct gpio_chip *chip, unsigned int offset)
{
struct tz1090_gpio_bank *bank = gpiochip_get_data(chip);
pinctrl_free_gpio(chip->base + offset);
pinctrl_gpio_free(chip->base + offset);
tz1090_gpio_clear_bit(bank, REG_GPIO_BIT_EN, offset);
}
......
......@@ -1962,7 +1962,7 @@ static inline void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip)
*/
int gpiochip_generic_request(struct gpio_chip *chip, unsigned offset)
{
return pinctrl_request_gpio(chip->gpiodev->base + offset);
return pinctrl_gpio_request(chip->gpiodev->base + offset);
}
EXPORT_SYMBOL_GPL(gpiochip_generic_request);
......@@ -1973,7 +1973,7 @@ EXPORT_SYMBOL_GPL(gpiochip_generic_request);
*/
void gpiochip_generic_free(struct gpio_chip *chip, unsigned offset)
{
pinctrl_free_gpio(chip->gpiodev->base + offset);
pinctrl_gpio_free(chip->gpiodev->base + offset);
}
EXPORT_SYMBOL_GPL(gpiochip_generic_free);
......
......@@ -2,11 +2,10 @@
# PINCTRL infrastructure and drivers
#
config PINCTRL
bool
menuconfig PINCTRL
bool "Pin controllers"
menu "Pin controllers"
depends on PINCTRL
if PINCTRL
config GENERIC_PINCTRL_GROUPS
bool
......@@ -33,7 +32,8 @@ config DEBUG_PINCTRL
config PINCTRL_ADI2
bool "ADI pin controller driver"
depends on BLACKFIN
depends on (BF54x || BF60x)
depends on !GPIO_ADI
select PINMUX
select IRQ_DOMAIN
help
......@@ -98,7 +98,8 @@ config PINCTRL_AT91PIO4
config PINCTRL_AMD
tristate "AMD GPIO pin control"
depends on GPIOLIB
depends on HAS_IOMEM
select GPIOLIB
select GPIOLIB_IRQCHIP
select PINMUX
select PINCONF
......@@ -152,12 +153,14 @@ config PINCTRL_GEMINI
depends on ARCH_GEMINI
default ARCH_GEMINI
select PINMUX
select GENERIC_PINCONF
select MFD_SYSCON
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
......@@ -168,16 +171,6 @@ config PINCTRL_MCP23S08
This provides a GPIO interface supporting inputs and outputs.
The I2C versions of the chips can be used as interrupt-controller.
config PINCTRL_MESON
bool
depends on OF
select PINMUX
select PINCONF
select GENERIC_PINCONF
select GPIOLIB
select OF_GPIO
select REGMAP_MMIO
config PINCTRL_OXNAS
bool
depends on OF
......@@ -210,6 +203,7 @@ config PINCTRL_RZA1
config PINCTRL_SINGLE
tristate "One-register-per-pin type device tree based pinctrl driver"
depends on OF
depends on HAS_IOMEM
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
select GENERIC_PINCONF
......@@ -226,10 +220,11 @@ config PINCTRL_SIRF
config PINCTRL_SX150X
bool "Semtech SX150x I2C GPIO expander pinctrl driver"
depends on GPIOLIB && I2C=y
depends on I2C=y
select PINMUX
select PINCONF
select GENERIC_PINCONF
select GPIOLIB
select GPIOLIB_IRQCHIP
select REGMAP
help
......@@ -369,6 +364,7 @@ source "drivers/pinctrl/uniphier/Kconfig"
source "drivers/pinctrl/vt8500/Kconfig"
source "drivers/pinctrl/mediatek/Kconfig"
source "drivers/pinctrl/zte/Kconfig"
source "drivers/pinctrl/meson/Kconfig"
config PINCTRL_XWAY
bool
......@@ -380,4 +376,4 @@ config PINCTRL_TB10X
depends on OF && ARC_PLAT_TB10X
select GPIOLIB
endmenu
endif
......@@ -311,7 +311,7 @@ static int iproc_gpio_request(struct gpio_chip *gc, unsigned offset)
if (!chip->pinmux_is_supported)
return 0;
return pinctrl_request_gpio(gpio);
return pinctrl_gpio_request(gpio);
}
static void iproc_gpio_free(struct gpio_chip *gc, unsigned offset)
......@@ -322,7 +322,7 @@ static void iproc_gpio_free(struct gpio_chip *gc, unsigned offset)
if (!chip->pinmux_is_supported)
return;
pinctrl_free_gpio(gpio);
pinctrl_gpio_free(gpio);
}
static int iproc_gpio_direction_input(struct gpio_chip *gc, unsigned gpio)
......
......@@ -275,23 +275,6 @@ static struct irq_chip nsp_gpio_irq_chip = {
.irq_set_type = nsp_gpio_irq_set_type,
};
/*
* Request the nsp IOMUX pinmux controller to mux individual pins to GPIO
*/
static int nsp_gpio_request(struct gpio_chip *gc, unsigned offset)
{
unsigned gpio = gc->base + offset;
return pinctrl_request_gpio(gpio);
}
static void nsp_gpio_free(struct gpio_chip *gc, unsigned offset)
{
unsigned gpio = gc->base + offset;
pinctrl_free_gpio(gpio);
}
static int nsp_gpio_direction_input(struct gpio_chip *gc, unsigned gpio)
{
struct nsp_gpio *chip = gpiochip_get_data(gc);
......@@ -670,8 +653,8 @@ static int nsp_gpio_probe(struct platform_device *pdev)
gc->label = dev_name(dev);
gc->parent = dev;
gc->of_node = dev->of_node;
gc->request = nsp_gpio_request;
gc->free = nsp_gpio_free;
gc->request = gpiochip_generic_request;
gc->free = gpiochip_generic_free;
gc->direction_input = nsp_gpio_direction_input;
gc->direction_output = nsp_gpio_direction_output;
gc->set = nsp_gpio_set;
......
......@@ -733,14 +733,14 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
}
/**
* pinctrl_request_gpio() - request a single pin to be used as GPIO
* pinctrl_gpio_request() - request a single pin to be used as GPIO
* @gpio: the GPIO pin number from the GPIO subsystem number space
*
* This function should *ONLY* be used from gpiolib-based GPIO drivers,
* as part of their gpio_request() semantics, platforms and individual drivers
* shall *NOT* request GPIO pins to be muxed in.
*/
int pinctrl_request_gpio(unsigned gpio)
int pinctrl_gpio_request(unsigned gpio)
{
struct pinctrl_dev *pctldev;
struct pinctrl_gpio_range *range;
......@@ -765,17 +765,17 @@ int pinctrl_request_gpio(unsigned gpio)
return ret;
}
EXPORT_SYMBOL_GPL(pinctrl_request_gpio);
EXPORT_SYMBOL_GPL(pinctrl_gpio_request);
/**
* pinctrl_free_gpio() - free control on a single pin, currently used as GPIO
* pinctrl_gpio_free() - free control on a single pin, currently used as GPIO
* @gpio: the GPIO pin number from the GPIO subsystem number space
*
* This function should *ONLY* be used from gpiolib-based GPIO drivers,
* as part of their gpio_free() semantics, platforms and individual drivers
* shall *NOT* request GPIO pins to be muxed out.
*/
void pinctrl_free_gpio(unsigned gpio)
void pinctrl_gpio_free(unsigned gpio)
{
struct pinctrl_dev *pctldev;
struct pinctrl_gpio_range *range;
......@@ -795,7 +795,7 @@ void pinctrl_free_gpio(unsigned gpio)
mutex_unlock(&pctldev->mutex);
}
EXPORT_SYMBOL_GPL(pinctrl_free_gpio);
EXPORT_SYMBOL_GPL(pinctrl_gpio_free);
static int pinctrl_gpio_direction(unsigned gpio, bool input)
{
......
......@@ -154,7 +154,7 @@ struct pinctrl_setting {
* or pin, and each of these will increment the @usecount.
* @mux_owner: The name of device that called pinctrl_get().
* @mux_setting: The most recent selected mux setting for this pin, if any.
* @gpio_owner: If pinctrl_request_gpio() was called for this pin, this is
* @gpio_owner: If pinctrl_gpio_request() was called for this pin, this is
* the name of the GPIO that "owns" this pin.
*/
struct pin_desc {
......
......@@ -5,7 +5,8 @@ if (X86 || COMPILE_TEST)
config PINCTRL_BAYTRAIL
bool "Intel Baytrail GPIO pin control"
depends on GPIOLIB && ACPI
depends on ACPI
select GPIOLIB
select GPIOLIB_IRQCHIP
select PINMUX
select PINCONF
......@@ -65,6 +66,14 @@ config PINCTRL_CANNONLAKE
This pinctrl driver provides an interface that allows configuring
of Intel Cannon Lake PCH pins and using them as GPIOs.
config PINCTRL_CEDARFORK
tristate "Intel Cedar Fork pinctrl and GPIO driver"
depends on ACPI
select PINCTRL_INTEL
help
This pinctrl driver provides an interface that allows configuring
of Intel Cedar Fork PCH pins and using them as GPIOs.
config PINCTRL_DENVERTON
tristate "Intel Denverton pinctrl and GPIO driver"
depends on ACPI
......
......@@ -7,6 +7,7 @@ obj-$(CONFIG_PINCTRL_MERRIFIELD) += pinctrl-merrifield.o
obj-$(CONFIG_PINCTRL_INTEL) += pinctrl-intel.o
obj-$(CONFIG_PINCTRL_BROXTON) += pinctrl-broxton.o
obj-$(CONFIG_PINCTRL_CANNONLAKE) += pinctrl-cannonlake.o
obj-$(CONFIG_PINCTRL_CEDARFORK) += pinctrl-cedarfork.o
obj-$(CONFIG_PINCTRL_DENVERTON) += pinctrl-denverton.o
obj-$(CONFIG_PINCTRL_GEMINILAKE) += pinctrl-geminilake.o
obj-$(CONFIG_PINCTRL_LEWISBURG) += pinctrl-lewisburg.o
......
/*
* Intel Cedar Fork PCH pinctrl/GPIO driver
*
* Copyright (C) 2017, Intel Corporation
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pinctrl/pinctrl.h>
#include "pinctrl-intel.h"
#define CDF_PAD_OWN 0x020
#define CDF_PADCFGLOCK 0x0c0
#define CDF_HOSTSW_OWN 0x120
#define CDF_GPI_IS 0x200
#define CDF_GPI_IE 0x230
#define CDF_GPP(r, s, e) \
{ \
.reg_num = (r), \
.base = (s), \
.size = ((e) - (s) + 1), \
}
#define CDF_COMMUNITY(b, s, e, g) \
{ \
.barno = (b), \
.padown_offset = CDF_PAD_OWN, \
.padcfglock_offset = CDF_PADCFGLOCK, \
.hostown_offset = CDF_HOSTSW_OWN, \
.is_offset = CDF_GPI_IS, \
.ie_offset = CDF_GPI_IE, \
.pin_base = (s), \
.npins = ((e) - (s) + 1), \
.gpps = (g), \
.ngpps = ARRAY_SIZE(g), \
}
/* Cedar Fork PCH */
static const struct pinctrl_pin_desc cdf_pins[] = {
/* WEST2 */
PINCTRL_PIN(0, "GBE_SDP_TIMESYNC0_S2N"),
PINCTRL_PIN(1, "GBE_SDP_TIMESYNC1_S2N"),
PINCTRL_PIN(2, "GBE_SDP_TIMESYNC2_S2N"),
PINCTRL_PIN(3, "GBE_SDP_TIMESYNC3_S2N"),
PINCTRL_PIN(4, "GBE0_I2C_CLK"),
PINCTRL_PIN(5, "GBE0_I2C_DATA"),
PINCTRL_PIN(6, "GBE1_I2C_CLK"),
PINCTRL_PIN(7, "GBE1_I2C_DATA"),
PINCTRL_PIN(8, "GBE2_I2C_CLK"),
PINCTRL_PIN(9, "GBE2_I2C_DATA"),
PINCTRL_PIN(10, "GBE3_I2C_CLK"),
PINCTRL_PIN(11, "GBE3_I2C_DATA"),
PINCTRL_PIN(12, "GBE0_LED0"),
PINCTRL_PIN(13, "GBE0_LED1"),
PINCTRL_PIN(14, "GBE0_LED2"),
PINCTRL_PIN(15, "GBE1_LED0"),
PINCTRL_PIN(16, "GBE1_LED1"),
PINCTRL_PIN(17, "GBE1_LED2"),
PINCTRL_PIN(18, "GBE2_LED0"),
PINCTRL_PIN(19, "GBE2_LED1"),
PINCTRL_PIN(20, "GBE2_LED2"),
PINCTRL_PIN(21, "GBE3_LED0"),
PINCTRL_PIN(22, "GBE3_LED1"),
PINCTRL_PIN(23, "GBE3_LED2"),
/* WEST3 */
PINCTRL_PIN(24, "NCSI_RXD0"),
PINCTRL_PIN(25, "NCSI_CLK_IN"),
PINCTRL_PIN(26, "NCSI_RXD1"),
PINCTRL_PIN(27, "NCSI_CRS_DV"),
PINCTRL_PIN(28, "NCSI_ARB_IN"),
PINCTRL_PIN(29, "NCSI_TX_EN"),
PINCTRL_PIN(30, "NCSI_TXD0"),
PINCTRL_PIN(31, "NCSI_TXD1"),
PINCTRL_PIN(32, "NCSI_ARB_OUT"),
PINCTRL_PIN(33, "GBE_SMB_CLK"),
PINCTRL_PIN(34, "GBE_SMB_DATA"),
PINCTRL_PIN(35, "GBE_SMB_ALRT_N"),
PINCTRL_PIN(36, "THERMTRIP_N"),
PINCTRL_PIN(37, "PCHHOT_N"),
PINCTRL_PIN(38, "ERROR0_N"),
PINCTRL_PIN(39, "ERROR1_N"),
PINCTRL_PIN(40, "ERROR2_N"),
PINCTRL_PIN(41, "MSMI_N"),
PINCTRL_PIN(42, "CATERR_N"),
PINCTRL_PIN(43, "MEMTRIP_N"),
PINCTRL_PIN(44, "UART0_RXD"),
PINCTRL_PIN(45, "UART0_TXD"),
PINCTRL_PIN(46, "UART1_RXD"),
PINCTRL_PIN(47, "UART1_TXD"),
/* WEST01 */
PINCTRL_PIN(48, "GBE_GPIO13"),
PINCTRL_PIN(49, "AUX_PWR"),
PINCTRL_PIN(50, "CPU_GP_2"),
PINCTRL_PIN(51, "CPU_GP_3"),
PINCTRL_PIN(52, "FAN_PWM_0"),
PINCTRL_PIN(53, "FAN_PWM_1"),
PINCTRL_PIN(54, "FAN_PWM_2"),
PINCTRL_PIN(55, "FAN_PWM_3"),
PINCTRL_PIN(56, "FAN_TACH_0"),
PINCTRL_PIN(57, "FAN_TACH_1"),
PINCTRL_PIN(58, "FAN_TACH_2"),
PINCTRL_PIN(59, "FAN_TACH_3"),
PINCTRL_PIN(60, "ME_SMB0_CLK"),
PINCTRL_PIN(61, "ME_SMB0_DATA"),
PINCTRL_PIN(62, "ME_SMB0_ALRT_N"),
PINCTRL_PIN(63, "ME_SMB1_CLK"),
PINCTRL_PIN(64, "ME_SMB1_DATA"),
PINCTRL_PIN(65, "ME_SMB1_ALRT_N"),
PINCTRL_PIN(66, "ME_SMB2_CLK"),
PINCTRL_PIN(67, "ME_SMB2_DATA"),
PINCTRL_PIN(68, "ME_SMB2_ALRT_N"),
PINCTRL_PIN(69, "GBE_MNG_I2C_CLK"),
PINCTRL_PIN(70, "GBE_MNG_I2C_DATA"),
/* WEST5 */
PINCTRL_PIN(71, "IE_UART_RXD"),
PINCTRL_PIN(72, "IE_UART_TXD"),
PINCTRL_PIN(73, "VPP_SMB_CLK"),
PINCTRL_PIN(74, "VPP_SMB_DATA"),
PINCTRL_PIN(75, "VPP_SMB_ALRT_N"),
PINCTRL_PIN(76, "PCIE_CLKREQ0_N"),
PINCTRL_PIN(77, "PCIE_CLKREQ1_N"),
PINCTRL_PIN(78, "PCIE_CLKREQ2_N"),
PINCTRL_PIN(79, "PCIE_CLKREQ3_N"),
PINCTRL_PIN(80, "PCIE_CLKREQ4_N"),
PINCTRL_PIN(81, "PCIE_CLKREQ5_N"),
PINCTRL_PIN(82, "PCIE_CLKREQ6_N"),
PINCTRL_PIN(83, "PCIE_CLKREQ7_N"),
PINCTRL_PIN(84, "PCIE_CLKREQ8_N"),
PINCTRL_PIN(85, "PCIE_CLKREQ9_N"),
PINCTRL_PIN(86, "FLEX_CLK_SE0"),
PINCTRL_PIN(87, "FLEX_CLK_SE1"),
PINCTRL_PIN(88, "FLEX_CLK1_50"),
PINCTRL_PIN(89, "FLEX_CLK2_50"),
PINCTRL_PIN(90, "FLEX_CLK_125"),
/* WESTC */
PINCTRL_PIN(91, "TCK_PCH"),
PINCTRL_PIN(92, "JTAGX_PCH"),
PINCTRL_PIN(93, "TRST_N_PCH"),
PINCTRL_PIN(94, "TMS_PCH"),
PINCTRL_PIN(95, "TDI_PCH"),
PINCTRL_PIN(96, "TDO_PCH"),
/* WESTC_DFX */
PINCTRL_PIN(97, "CX_PRDY_N"),
PINCTRL_PIN(98, "CX_PREQ_N"),
PINCTRL_PIN(99, "CPU_FBREAK_OUT_N"),
PINCTRL_PIN(100, "TRIGGER0_N"),
PINCTRL_PIN(101, "TRIGGER1_N"),
/* WESTA */
PINCTRL_PIN(102, "DBG_PTI_CLK0"),
PINCTRL_PIN(103, "DBG_PTI_CLK3"),
PINCTRL_PIN(104, "DBG_PTI_DATA0"),
PINCTRL_PIN(105, "DBG_PTI_DATA1"),
PINCTRL_PIN(106, "DBG_PTI_DATA2"),
PINCTRL_PIN(107, "DBG_PTI_DATA3"),
PINCTRL_PIN(108, "DBG_PTI_DATA4"),
PINCTRL_PIN(109, "DBG_PTI_DATA5"),
PINCTRL_PIN(110, "DBG_PTI_DATA6"),
PINCTRL_PIN(111, "DBG_PTI_DATA7"),
/* WESTB */
PINCTRL_PIN(112, "DBG_PTI_DATA8"),
PINCTRL_PIN(113, "DBG_PTI_DATA9"),
PINCTRL_PIN(114, "DBG_PTI_DATA10"),
PINCTRL_PIN(115, "DBG_PTI_DATA11"),
PINCTRL_PIN(116, "DBG_PTI_DATA12"),
PINCTRL_PIN(117, "DBG_PTI_DATA13"),
PINCTRL_PIN(118, "DBG_PTI_DATA14"),
PINCTRL_PIN(119, "DBG_PTI_DATA15"),
PINCTRL_PIN(120, "DBG_SPARE0"),
PINCTRL_PIN(121, "DBG_SPARE1"),
PINCTRL_PIN(122, "DBG_SPARE2"),
PINCTRL_PIN(123, "DBG_SPARE3"),
/* WESTD */
PINCTRL_PIN(124, "CPU_PWR_GOOD"),
PINCTRL_PIN(125, "PLTRST_CPU_N"),
PINCTRL_PIN(126, "NAC_RESET_NAC_N"),
PINCTRL_PIN(127, "PCH_SBLINK_RX"),
PINCTRL_PIN(128, "PCH_SBLINK_TX"),
PINCTRL_PIN(129, "PMSYNC_CLK"),
PINCTRL_PIN(130, "CPU_ERR0_N"),
PINCTRL_PIN(131, "CPU_ERR1_N"),
PINCTRL_PIN(132, "CPU_ERR2_N"),
PINCTRL_PIN(133, "CPU_THERMTRIP_N"),
PINCTRL_PIN(134, "CPU_MSMI_N"),
PINCTRL_PIN(135, "CPU_CATERR_N"),
PINCTRL_PIN(136, "CPU_MEMTRIP_N"),
PINCTRL_PIN(137, "NAC_GR_N"),
PINCTRL_PIN(138, "NAC_XTAL_VALID"),
PINCTRL_PIN(139, "NAC_WAKE_N"),
PINCTRL_PIN(140, "NAC_SBLINK_CLK_S2N"),
PINCTRL_PIN(141, "NAC_SBLINK_N2S"),
PINCTRL_PIN(142, "NAC_SBLINK_S2N"),
PINCTRL_PIN(143, "NAC_SBLINK_CLK_N2S"),
/* WESTD_PECI */
PINCTRL_PIN(144, "ME_PECI"),
/* WESTF */
PINCTRL_PIN(145, "NAC_RMII_CLK"),
PINCTRL_PIN(146, "NAC_RGMII_CLK"),
PINCTRL_PIN(147, "NAC_SPARE0"),
PINCTRL_PIN(148, "NAC_SPARE1"),
PINCTRL_PIN(149, "NAC_SPARE2"),
PINCTRL_PIN(150, "NAC_INIT_SX_WAKE_N"),
PINCTRL_PIN(151, "NAC_GBE_GPIO0_S2N"),
PINCTRL_PIN(152, "NAC_GBE_GPIO1_S2N"),
PINCTRL_PIN(153, "NAC_GBE_GPIO2_S2N"),
PINCTRL_PIN(154, "NAC_GBE_GPIO3_S2N"),
PINCTRL_PIN(155, "NAC_NCSI_RXD0"),
PINCTRL_PIN(156, "NAC_NCSI_CLK_IN"),
PINCTRL_PIN(157, "NAC_NCSI_RXD1"),
PINCTRL_PIN(158, "NAC_NCSI_CRS_DV"),
PINCTRL_PIN(159, "NAC_NCSI_ARB_IN"),
PINCTRL_PIN(160, "NAC_NCSI_TX_EN"),
PINCTRL_PIN(161, "NAC_NCSI_TXD0"),
PINCTRL_PIN(162, "NAC_NCSI_TXD1"),
PINCTRL_PIN(163, "NAC_NCSI_ARB_OUT"),
PINCTRL_PIN(164, "NAC_NCSI_OE_N"),
PINCTRL_PIN(165, "NAC_GBE_SMB_CLK"),
PINCTRL_PIN(166, "NAC_GBE_SMB_DATA"),
PINCTRL_PIN(167, "NAC_GBE_SMB_ALRT_N"),
/* EAST2 */
PINCTRL_PIN(168, "USB_OC0_N"),
PINCTRL_PIN(169, "GBE_GPIO0"),
PINCTRL_PIN(170, "GBE_GPIO1"),
PINCTRL_PIN(171, "GBE_GPIO2"),
PINCTRL_PIN(172, "GBE_GPIO3"),
PINCTRL_PIN(173, "GBE_GPIO4"),
PINCTRL_PIN(174, "GBE_GPIO5"),
PINCTRL_PIN(175, "GBE_GPIO6"),
PINCTRL_PIN(176, "GBE_GPIO7"),
PINCTRL_PIN(177, "GBE_GPIO8"),
PINCTRL_PIN(178, "GBE_GPIO9"),
PINCTRL_PIN(179, "GBE_GPIO10"),
PINCTRL_PIN(180, "GBE_GPIO11"),
PINCTRL_PIN(181, "GBE_GPIO12"),
PINCTRL_PIN(182, "SATA0_LED_N"),
PINCTRL_PIN(183, "SATA1_LED_N"),
PINCTRL_PIN(184, "SATA_PDETECT0"),
PINCTRL_PIN(185, "SATA_PDETECT1"),
PINCTRL_PIN(186, "SATA0_SDOUT"),
PINCTRL_PIN(187, "SATA1_SDOUT"),
PINCTRL_PIN(188, "SATA2_LED_N"),
PINCTRL_PIN(189, "SATA_PDETECT2"),
PINCTRL_PIN(190, "SATA2_SDOUT"),
/* EAST3 */
PINCTRL_PIN(191, "ESPI_IO0"),
PINCTRL_PIN(192, "ESPI_IO1"),
PINCTRL_PIN(193, "ESPI_IO2"),
PINCTRL_PIN(194, "ESPI_IO3"),
PINCTRL_PIN(195, "ESPI_CLK"),
PINCTRL_PIN(196, "ESPI_RST_N"),
PINCTRL_PIN(197, "ESPI_CS0_N"),
PINCTRL_PIN(198, "ESPI_ALRT0_N"),
PINCTRL_PIN(199, "ESPI_CS1_N"),
PINCTRL_PIN(200, "ESPI_ALRT1_N"),
PINCTRL_PIN(201, "ESPI_CLK_LOOPBK"),
/* EAST0 */
PINCTRL_PIN(202, "SPI_CS0_N"),
PINCTRL_PIN(203, "SPI_CS1_N"),
PINCTRL_PIN(204, "SPI_MOSI_IO0"),
PINCTRL_PIN(205, "SPI_MISO_IO1"),
PINCTRL_PIN(206, "SPI_IO2"),
PINCTRL_PIN(207, "SPI_IO3"),
PINCTRL_PIN(208, "SPI_CLK"),
PINCTRL_PIN(209, "SPI_CLK_LOOPBK"),
PINCTRL_PIN(210, "SUSPWRDNACK"),
PINCTRL_PIN(211, "PMU_SUSCLK"),
PINCTRL_PIN(212, "ADR_COMPLETE"),
PINCTRL_PIN(213, "ADR_TRIGGER_N"),
PINCTRL_PIN(214, "PMU_SLP_S45_N"),
PINCTRL_PIN(215, "PMU_SLP_S3_N"),
PINCTRL_PIN(216, "PMU_WAKE_N"),
PINCTRL_PIN(217, "PMU_PWRBTN_N"),
PINCTRL_PIN(218, "PMU_RESETBUTTON_N"),
PINCTRL_PIN(219, "PMU_PLTRST_N"),
PINCTRL_PIN(220, "SUS_STAT_N"),
PINCTRL_PIN(221, "PMU_I2C_CLK"),
PINCTRL_PIN(222, "PMU_I2C_DATA"),
PINCTRL_PIN(223, "PECI_SMB_CLK"),
PINCTRL_PIN(224, "PECI_SMB_DATA"),
PINCTRL_PIN(225, "PECI_SMB_ALRT_N"),
/* EMMC */
PINCTRL_PIN(226, "EMMC_CMD"),
PINCTRL_PIN(227, "EMMC_STROBE"),
PINCTRL_PIN(228, "EMMC_CLK"),
PINCTRL_PIN(229, "EMMC_D0"),
PINCTRL_PIN(230, "EMMC_D1"),
PINCTRL_PIN(231, "EMMC_D2"),
PINCTRL_PIN(232, "EMMC_D3"),
PINCTRL_PIN(233, "EMMC_D4"),
PINCTRL_PIN(234, "EMMC_D5"),
PINCTRL_PIN(235, "EMMC_D6"),
PINCTRL_PIN(236, "EMMC_D7"),
};
static const struct intel_padgroup cdf_community0_gpps[] = {
CDF_GPP(0, 0, 23), /* WEST2 */
CDF_GPP(1, 24, 47), /* WEST3 */
CDF_GPP(2, 48, 70), /* WEST01 */
CDF_GPP(3, 71, 90), /* WEST5 */
CDF_GPP(4, 91, 96), /* WESTC */
CDF_GPP(5, 97, 101), /* WESTC_DFX */
CDF_GPP(6, 102, 111), /* WESTA */
CDF_GPP(7, 112, 123), /* WESTB */
CDF_GPP(8, 124, 143), /* WESTD */
CDF_GPP(9, 144, 144), /* WESTD_PECI */
CDF_GPP(10, 145, 167), /* WESTF */
};
static const struct intel_padgroup cdf_community1_gpps[] = {
CDF_GPP(0, 168, 190), /* EAST2 */
CDF_GPP(1, 191, 201), /* EAST3 */
CDF_GPP(2, 202, 225), /* EAST0 */
CDF_GPP(3, 226, 236), /* EMMC */
};
static const struct intel_community cdf_communities[] = {
CDF_COMMUNITY(0, 0, 167, cdf_community0_gpps), /* West */
CDF_COMMUNITY(1, 168, 236, cdf_community1_gpps), /* East */
};
static const struct intel_pinctrl_soc_data cdf_soc_data = {
.pins = cdf_pins,
.npins = ARRAY_SIZE(cdf_pins),
.communities = cdf_communities,
.ncommunities = ARRAY_SIZE(cdf_communities),
};
static int cdf_pinctrl_probe(struct platform_device *pdev)
{
return intel_pinctrl_probe(pdev, &cdf_soc_data);
}
static const struct dev_pm_ops cdf_pinctrl_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend,
intel_pinctrl_resume)
};
static const struct acpi_device_id cdf_pinctrl_acpi_match[] = {
{ "INTC3001" },
{ }
};
MODULE_DEVICE_TABLE(acpi, cdf_pinctrl_acpi_match);
static struct platform_driver cdf_pinctrl_driver = {
.probe = cdf_pinctrl_probe,
.driver = {
.name = "cedarfork-pinctrl",
.acpi_match_table = cdf_pinctrl_acpi_match,
.pm = &cdf_pinctrl_pm_ops,
},
};
static int __init cdf_pinctrl_init(void)
{
return platform_driver_register(&cdf_pinctrl_driver);
}
subsys_initcall(cdf_pinctrl_init);
static void __exit cdf_pinctrl_exit(void)
{
platform_driver_unregister(&cdf_pinctrl_driver);
}
module_exit(cdf_pinctrl_exit);
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
MODULE_DESCRIPTION("Intel Cedar Fork PCH pinctrl/GPIO driver");
MODULE_LICENSE("GPL v2");
......@@ -491,7 +491,7 @@ static const struct chv_community north_community = {
.ngpio_ranges = ARRAY_SIZE(north_gpio_ranges),
.ngpios = ARRAY_SIZE(north_pins),
/*
* North community can benerate GPIO interrupts only for the first
* North community can generate GPIO interrupts only for the first
* 8 interrupts. The upper half (8-15) can only be used to trigger
* GPEs.
*/
......
......@@ -30,8 +30,6 @@
#define PADBAR 0x00c
#define GPI_IS 0x100
#define GPI_GPE_STS 0x140
#define GPI_GPE_EN 0x160
#define PADOWN_BITS 4
#define PADOWN_SHIFT(p) ((p) % 8 * PADOWN_BITS)
......@@ -818,7 +816,7 @@ static void intel_gpio_irq_ack(struct irq_data *d)
community = intel_get_community(pctrl, pin);
if (community) {
const struct intel_padgroup *padgrp;
unsigned gpp, gpp_offset;
unsigned gpp, gpp_offset, is_offset;
padgrp = intel_community_get_padgroup(community, pin);
if (!padgrp)
......@@ -826,9 +824,10 @@ static void intel_gpio_irq_ack(struct irq_data *d)
gpp = padgrp->reg_num;
gpp_offset = padgroup_offset(padgrp, pin);
is_offset = community->is_offset + gpp * 4;
raw_spin_lock(&pctrl->lock);
writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4);
writel(BIT(gpp_offset), community->regs + is_offset);
raw_spin_unlock(&pctrl->lock);
}
}
......@@ -843,7 +842,7 @@ static void intel_gpio_irq_enable(struct irq_data *d)
community = intel_get_community(pctrl, pin);
if (community) {
const struct intel_padgroup *padgrp;
unsigned gpp, gpp_offset;
unsigned gpp, gpp_offset, is_offset;
unsigned long flags;
u32 value;
......@@ -853,10 +852,11 @@ static void intel_gpio_irq_enable(struct irq_data *d)
gpp = padgrp->reg_num;
gpp_offset = padgroup_offset(padgrp, pin);
is_offset = community->is_offset + gpp * 4;
raw_spin_lock_irqsave(&pctrl->lock, flags);
/* Clear interrupt status first to avoid unexpected interrupt */
writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4);
writel(BIT(gpp_offset), community->regs + is_offset);
value = readl(community->regs + community->ie_offset + gpp * 4);
value |= BIT(gpp_offset);
......@@ -991,7 +991,8 @@ static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl,
const struct intel_padgroup *padgrp = &community->gpps[gpp];
unsigned long pending, enabled, gpp_offset;
pending = readl(community->regs + GPI_IS + padgrp->reg_num * 4);
pending = readl(community->regs + community->is_offset +
padgrp->reg_num * 4);
enabled = readl(community->regs + community->ie_offset +
padgrp->reg_num * 4);
......@@ -1241,6 +1242,9 @@ int intel_pinctrl_probe(struct platform_device *pdev,
community->regs = regs;
community->pad_regs = regs + padbar;
if (!community->is_offset)
community->is_offset = GPI_IS;
ret = intel_pinctrl_add_padgroups(pctrl, community);
if (ret)
return ret;
......@@ -1356,7 +1360,7 @@ static void intel_gpio_irq_init(struct intel_pinctrl *pctrl)
for (gpp = 0; gpp < community->ngpps; gpp++) {
/* Mask and clear all interrupts */
writel(0, base + community->ie_offset + gpp * 4);
writel(0xffff, base + GPI_IS + gpp * 4);
writel(0xffff, base + community->is_offset + gpp * 4);
}
}
}
......
......@@ -73,6 +73,8 @@ struct intel_padgroup {
* @hostown_offset: Register offset of HOSTSW_OWN from @regs. If %0 then it
* is assumed that the host owns the pin (rather than
* ACPI).
* @is_offset: Register offset of GPI_IS from @regs. If %0 then uses the
* default (%0x100).
* @ie_offset: Register offset of GPI_IE from @regs.
* @pin_base: Starting pin of pins in this community
* @gpp_size: Maximum number of pads in each group, such as PADCFGLOCK,
......@@ -98,6 +100,7 @@ struct intel_community {
unsigned padown_offset;
unsigned padcfglock_offset;
unsigned hostown_offset;
unsigned is_offset;
unsigned ie_offset;
unsigned pin_base;
unsigned gpp_size;
......
menuconfig PINCTRL_MESON
bool "Amlogic SoC pinctrl drivers"
depends on ARCH_MESON
depends on OF
select PINMUX
select PINCONF
select GENERIC_PINCONF
select GPIOLIB
select OF_GPIO
select REGMAP_MMIO
if PINCTRL_MESON
config PINCTRL_MESON8
bool "Meson 8 SoC pinctrl driver"
depends on ARM
select PINCTRL_MESON8_PMX
default y
config PINCTRL_MESON8B
bool "Meson 8b SoC pinctrl driver"
depends on ARM
select PINCTRL_MESON8_PMX
default y
config PINCTRL_MESON_GXBB
bool "Meson gxbb SoC pinctrl driver"
depends on ARM64
select PINCTRL_MESON8_PMX
default y
config PINCTRL_MESON_GXL
bool "Meson gxl SoC pinctrl driver"
depends on ARM64
select PINCTRL_MESON8_PMX
default y
config PINCTRL_MESON8_PMX
bool
endif
obj-y += pinctrl-meson8.o pinctrl-meson8b.o
obj-y += pinctrl-meson-gxbb.o pinctrl-meson-gxl.o
obj-y += pinctrl-meson.o
obj-$(CONFIG_PINCTRL_MESON) += pinctrl-meson.o
obj-$(CONFIG_PINCTRL_MESON8_PMX) += pinctrl-meson8-pmx.o
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
......@@ -31,10 +31,6 @@
* In some cases the register ranges for pull enable and pull
* direction are the same and thus there are only 3 register ranges.
*
* Every pinmux group can be enabled by a specific bit in the first
* register range; when all groups for a given pin are disabled the
* pin acts as a GPIO.
*
* For the pull and GPIO configuration every bank uses a contiguous
* set of bits in the register sets described above; the same register
* can be shared by more banks with different offsets.
......@@ -50,6 +46,7 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
......@@ -147,94 +144,24 @@ static const struct pinctrl_ops meson_pctrl_ops = {
.pin_dbg_show = meson_pin_dbg_show,
};
/**
* meson_pmx_disable_other_groups() - disable other groups using a given pin
*
* @pc: meson pin controller device
* @pin: number of the pin
* @sel_group: index of the selected group, or -1 if none
*
* The function disables all pinmux groups using a pin except the
* selected one. If @sel_group is -1 all groups are disabled, leaving
* the pin in GPIO mode.
*/
static void meson_pmx_disable_other_groups(struct meson_pinctrl *pc,
unsigned int pin, int sel_group)
{
struct meson_pmx_group *group;
int i, j;
for (i = 0; i < pc->data->num_groups; i++) {
group = &pc->data->groups[i];
if (group->is_gpio || i == sel_group)
continue;
for (j = 0; j < group->num_pins; j++) {
if (group->pins[j] == pin) {
/* We have found a group using the pin */
regmap_update_bits(pc->reg_mux,
group->reg * 4,
BIT(group->bit), 0);
}
}
}
}
static int meson_pmx_set_mux(struct pinctrl_dev *pcdev, unsigned func_num,
unsigned group_num)
{
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];
int i, ret = 0;
dev_dbg(pc->dev, "enable function %s, group %s\n", func->name,
group->name);
/*
* Disable groups using the same pin.
* The selected group is not disabled to avoid glitches.
*/
for (i = 0; i < group->num_pins; i++)
meson_pmx_disable_other_groups(pc, group->pins[i], group_num);
/* Function 0 (GPIO) doesn't need any additional setting */
if (func_num)
ret = regmap_update_bits(pc->reg_mux, group->reg * 4,
BIT(group->bit), BIT(group->bit));
return ret;
}
static int meson_pmx_request_gpio(struct pinctrl_dev *pcdev,
struct pinctrl_gpio_range *range,
unsigned offset)
{
struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
meson_pmx_disable_other_groups(pc, offset, -1);
return 0;
}
static int meson_pmx_get_funcs_count(struct pinctrl_dev *pcdev)
int meson_pmx_get_funcs_count(struct pinctrl_dev *pcdev)
{
struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
return pc->data->num_funcs;
}
static const char *meson_pmx_get_func_name(struct pinctrl_dev *pcdev,
unsigned selector)
const char *meson_pmx_get_func_name(struct pinctrl_dev *pcdev,
unsigned selector)
{
struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
return pc->data->funcs[selector].name;
}
static int meson_pmx_get_groups(struct pinctrl_dev *pcdev, unsigned selector,
const char * const **groups,
unsigned * const num_groups)
int meson_pmx_get_groups(struct pinctrl_dev *pcdev, unsigned selector,
const char * const **groups,
unsigned * const num_groups)
{
struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
......@@ -244,14 +171,6 @@ static int meson_pmx_get_groups(struct pinctrl_dev *pcdev, unsigned selector,
return 0;
}
static const struct pinmux_ops meson_pmx_ops = {
.set_mux = meson_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_pmx_request_gpio,
};
static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
unsigned long *configs, unsigned num_configs)
{
......@@ -399,7 +318,7 @@ static int meson_pinconf_group_set(struct pinctrl_dev *pcdev,
static int meson_pinconf_group_get(struct pinctrl_dev *pcdev,
unsigned int group, unsigned long *config)
{
return -ENOSYS;
return -ENOTSUPP;
}
static const struct pinconf_ops meson_pinconf_ops = {
......@@ -410,31 +329,18 @@ static const struct pinconf_ops meson_pinconf_ops = {
.is_generic = true,
};
static int meson_gpio_request(struct gpio_chip *chip, unsigned gpio)
{
return pinctrl_request_gpio(chip->base + gpio);
}
static void meson_gpio_free(struct gpio_chip *chip, unsigned gpio)
{
struct meson_pinctrl *pc = gpiochip_get_data(chip);
pinctrl_free_gpio(pc->data->pin_base + gpio);
}
static int meson_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
{
struct meson_pinctrl *pc = gpiochip_get_data(chip);
unsigned int reg, bit, pin;
unsigned int reg, bit;
struct meson_bank *bank;
int ret;
pin = pc->data->pin_base + gpio;
ret = meson_get_bank(pc, pin, &bank);
ret = meson_get_bank(pc, gpio, &bank);
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_DIR, &reg, &bit);
meson_calc_reg_and_bit(bank, gpio, REG_DIR, &reg, &bit);
return regmap_update_bits(pc->reg_gpio, reg, BIT(bit), BIT(bit));
}
......@@ -443,21 +349,20 @@ static int meson_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
int value)
{
struct meson_pinctrl *pc = gpiochip_get_data(chip);
unsigned int reg, bit, pin;
unsigned int reg, bit;
struct meson_bank *bank;
int ret;
pin = pc->data->pin_base + gpio;
ret = meson_get_bank(pc, pin, &bank);
ret = meson_get_bank(pc, gpio, &bank);
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_DIR, &reg, &bit);
meson_calc_reg_and_bit(bank, gpio, REG_DIR, &reg, &bit);
ret = regmap_update_bits(pc->reg_gpio, reg, BIT(bit), 0);
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_OUT, &reg, &bit);
meson_calc_reg_and_bit(bank, gpio, REG_OUT, &reg, &bit);
return regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
value ? BIT(bit) : 0);
}
......@@ -465,16 +370,15 @@ static int meson_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
static void meson_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
{
struct meson_pinctrl *pc = gpiochip_get_data(chip);
unsigned int reg, bit, pin;
unsigned int reg, bit;
struct meson_bank *bank;
int ret;
pin = pc->data->pin_base + gpio;
ret = meson_get_bank(pc, pin, &bank);
ret = meson_get_bank(pc, gpio, &bank);
if (ret)
return;
meson_calc_reg_and_bit(bank, pin, REG_OUT, &reg, &bit);
meson_calc_reg_and_bit(bank, gpio, REG_OUT, &reg, &bit);
regmap_update_bits(pc->reg_gpio, reg, BIT(bit),
value ? BIT(bit) : 0);
}
......@@ -482,70 +386,33 @@ static void meson_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)
{
struct meson_pinctrl *pc = gpiochip_get_data(chip);
unsigned int reg, bit, val, pin;
unsigned int reg, bit, val;
struct meson_bank *bank;
int ret;
pin = pc->data->pin_base + gpio;
ret = meson_get_bank(pc, pin, &bank);
ret = meson_get_bank(pc, gpio, &bank);
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_IN, &reg, &bit);
meson_calc_reg_and_bit(bank, gpio, REG_IN, &reg, &bit);
regmap_read(pc->reg_gpio, reg, &val);
return !!(val & BIT(bit));
}
static const struct of_device_id meson_pinctrl_dt_match[] = {
{
.compatible = "amlogic,meson8-cbus-pinctrl",
.data = &meson8_cbus_pinctrl_data,
},
{
.compatible = "amlogic,meson8b-cbus-pinctrl",
.data = &meson8b_cbus_pinctrl_data,
},
{
.compatible = "amlogic,meson8-aobus-pinctrl",
.data = &meson8_aobus_pinctrl_data,
},
{
.compatible = "amlogic,meson8b-aobus-pinctrl",
.data = &meson8b_aobus_pinctrl_data,
},
{
.compatible = "amlogic,meson-gxbb-periphs-pinctrl",
.data = &meson_gxbb_periphs_pinctrl_data,
},
{
.compatible = "amlogic,meson-gxbb-aobus-pinctrl",
.data = &meson_gxbb_aobus_pinctrl_data,
},
{
.compatible = "amlogic,meson-gxl-periphs-pinctrl",
.data = &meson_gxl_periphs_pinctrl_data,
},
{
.compatible = "amlogic,meson-gxl-aobus-pinctrl",
.data = &meson_gxl_aobus_pinctrl_data,
},
{ },
};
static int meson_gpiolib_register(struct meson_pinctrl *pc)
{
int ret;
pc->chip.label = pc->data->name;
pc->chip.parent = pc->dev;
pc->chip.request = meson_gpio_request;
pc->chip.free = meson_gpio_free;
pc->chip.request = gpiochip_generic_request;
pc->chip.free = gpiochip_generic_free;
pc->chip.direction_input = meson_gpio_direction_input;
pc->chip.direction_output = meson_gpio_direction_output;
pc->chip.get = meson_gpio_get;
pc->chip.set = meson_gpio_set;
pc->chip.base = pc->data->pin_base;
pc->chip.base = -1;
pc->chip.ngpio = pc->data->num_pins;
pc->chip.can_sleep = false;
pc->chip.of_node = pc->of_node;
......@@ -640,9 +507,8 @@ static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
return 0;
}
static int meson_pinctrl_probe(struct platform_device *pdev)
int meson_pinctrl_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
struct device *dev = &pdev->dev;
struct meson_pinctrl *pc;
int ret;
......@@ -652,17 +518,16 @@ static int meson_pinctrl_probe(struct platform_device *pdev)
return -ENOMEM;
pc->dev = dev;
match = of_match_node(meson_pinctrl_dt_match, pdev->dev.of_node);
pc->data = (struct meson_pinctrl_data *) match->data;
pc->data = (struct meson_pinctrl_data *) of_device_get_match_data(dev);
ret = meson_pinctrl_parse_dt(pc, pdev->dev.of_node);
ret = meson_pinctrl_parse_dt(pc, dev->of_node);
if (ret)
return ret;
pc->desc.name = "pinctrl-meson";
pc->desc.owner = THIS_MODULE;
pc->desc.pctlops = &meson_pctrl_ops;
pc->desc.pmxops = &meson_pmx_ops;
pc->desc.pmxops = pc->data->pmx_ops;
pc->desc.confops = &meson_pinconf_ops;
pc->desc.pins = pc->data->pins;
pc->desc.npins = pc->data->num_pins;
......@@ -675,12 +540,3 @@ static int meson_pinctrl_probe(struct platform_device *pdev)
return meson_gpiolib_register(pc);
}
static struct platform_driver meson_pinctrl_driver = {
.probe = meson_pinctrl_probe,
.driver = {
.name = "meson-pinctrl",
.of_match_table = meson_pinctrl_dt_match,
},
};
builtin_platform_driver(meson_pinctrl_driver);
......@@ -13,6 +13,7 @@
#include <linux/gpio.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/types.h>
......@@ -31,9 +32,7 @@ struct meson_pmx_group {
const char *name;
const unsigned int *pins;
unsigned int num_pins;
bool is_gpio;
unsigned int reg;
unsigned int bit;
const void *data;
};
/**
......@@ -103,12 +102,12 @@ struct meson_pinctrl_data {
const struct pinctrl_pin_desc *pins;
struct meson_pmx_group *groups;
struct meson_pmx_func *funcs;
unsigned int pin_base;
unsigned int num_pins;
unsigned int num_groups;
unsigned int num_funcs;
struct meson_bank *banks;
unsigned int num_banks;
const struct pinmux_ops *pmx_ops;
};
struct meson_pinctrl {
......@@ -124,25 +123,6 @@ struct meson_pinctrl {
struct device_node *of_node;
};
#define PIN(x, b) (b + x)
#define GROUP(grp, r, b) \
{ \
.name = #grp, \
.pins = grp ## _pins, \
.num_pins = ARRAY_SIZE(grp ## _pins), \
.reg = r, \
.bit = b, \
}
#define GPIO_GROUP(gpio, b) \
{ \
.name = #gpio, \
.pins = (const unsigned int[]){ PIN(gpio, b) }, \
.num_pins = 1, \
.is_gpio = true, \
}
#define FUNCTION(fn) \
{ \
.name = #fn, \
......@@ -166,13 +146,16 @@ struct meson_pinctrl {
}, \
}
#define MESON_PIN(x, b) PINCTRL_PIN(PIN(x, b), #x)
#define MESON_PIN(x) PINCTRL_PIN(x, #x)
/* Common pmx functions */
int meson_pmx_get_funcs_count(struct pinctrl_dev *pcdev);
const char *meson_pmx_get_func_name(struct pinctrl_dev *pcdev,
unsigned selector);
int meson_pmx_get_groups(struct pinctrl_dev *pcdev,
unsigned selector,
const char * const **groups,
unsigned * const num_groups);
extern struct meson_pinctrl_data meson8_cbus_pinctrl_data;
extern struct meson_pinctrl_data meson8_aobus_pinctrl_data;
extern struct meson_pinctrl_data meson8b_cbus_pinctrl_data;
extern struct meson_pinctrl_data meson8b_aobus_pinctrl_data;
extern struct meson_pinctrl_data meson_gxbb_periphs_pinctrl_data;
extern struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data;
extern struct meson_pinctrl_data meson_gxl_periphs_pinctrl_data;
extern struct meson_pinctrl_data meson_gxl_aobus_pinctrl_data;
/* Common probe function */
int meson_pinctrl_probe(struct platform_device *pdev);
/*
* First generation of pinmux driver for Amlogic Meson SoCs
*
* Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
* Copyright (C) 2017 Jerome Brunet <jbrunet@baylibre.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* For this first generation of pinctrl driver every pinmux group can be
* enabled by a specific bit in the first register range. When all groups for
* a given pin are disabled the pin acts as a GPIO.
*/
#include <linux/device.h>
#include <linux/regmap.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include "pinctrl-meson.h"
#include "pinctrl-meson8-pmx.h"
/**
* meson8_pmx_disable_other_groups() - disable other groups using a given pin
*
* @pc: meson pin controller device
* @pin: number of the pin
* @sel_group: index of the selected group, or -1 if none
*
* The function disables all pinmux groups using a pin except the
* selected one. If @sel_group is -1 all groups are disabled, leaving
* the pin in GPIO mode.
*/
static void meson8_pmx_disable_other_groups(struct meson_pinctrl *pc,
unsigned int pin, int sel_group)
{
struct meson_pmx_group *group;
struct meson8_pmx_data *pmx_data;
int i, j;
for (i = 0; i < pc->data->num_groups; i++) {
group = &pc->data->groups[i];
pmx_data = (struct meson8_pmx_data *)group->data;
if (pmx_data->is_gpio || i == sel_group)
continue;
for (j = 0; j < group->num_pins; j++) {
if (group->pins[j] == pin) {
/* We have found a group using the pin */
regmap_update_bits(pc->reg_mux,
pmx_data->reg * 4,
BIT(pmx_data->bit), 0);
}
}
}
}
static int meson8_pmx_set_mux(struct pinctrl_dev *pcdev, unsigned func_num,
unsigned group_num)
{
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 meson8_pmx_data *pmx_data =
(struct meson8_pmx_data *)group->data;
int i, ret = 0;
dev_dbg(pc->dev, "enable function %s, group %s\n", func->name,
group->name);
/*
* Disable groups using the same pin.
* The selected group is not disabled to avoid glitches.
*/
for (i = 0; i < group->num_pins; i++)
meson8_pmx_disable_other_groups(pc, group->pins[i], group_num);
/* Function 0 (GPIO) doesn't need any additional setting */
if (func_num)
ret = regmap_update_bits(pc->reg_mux, pmx_data->reg * 4,
BIT(pmx_data->bit),
BIT(pmx_data->bit));
return ret;
}
static int meson8_pmx_request_gpio(struct pinctrl_dev *pcdev,
struct pinctrl_gpio_range *range,
unsigned offset)
{
struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
meson8_pmx_disable_other_groups(pc, offset, -1);
return 0;
}
const struct pinmux_ops meson8_pmx_ops = {
.set_mux = meson8_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 = meson8_pmx_request_gpio,
};
/*
* First generation of pinmux driver for Amlogic Meson SoCs
*
* Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
* Copyright (C) 2017 Jerome Brunet <jbrunet@baylibre.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
struct meson8_pmx_data {
bool is_gpio;
unsigned int reg;
unsigned int bit;
};
#define PMX_DATA(r, b, g) \
{ \
.reg = r, \
.bit = b, \
.is_gpio = g, \
}
#define GROUP(grp, r, b) \
{ \
.name = #grp, \
.pins = grp ## _pins, \
.num_pins = ARRAY_SIZE(grp ## _pins), \
.data = (const struct meson8_pmx_data[]){ \
PMX_DATA(r, b, false), \
}, \
}
#define GPIO_GROUP(gpio) \
{ \
.name = #gpio, \
.pins = (const unsigned int[]){ gpio }, \
.num_pins = 1, \
.data = (const struct meson8_pmx_data[]){ \
PMX_DATA(0, 0, true), \
}, \
}
extern const struct pinmux_ops meson8_pmx_ops;
......@@ -576,6 +576,19 @@ static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
case IRQ_TYPE_EDGE_FALLING:
val |= (BIT(d->hwirq % GPIO_PER_REG));
break;
case IRQ_TYPE_EDGE_BOTH: {
u32 in_val, in_reg = INPUT_VAL;
armada_37xx_irq_update_reg(&in_reg, d);
regmap_read(info->regmap, in_reg, &in_val);
/* Set initial polarity based on current input level. */
if (in_val & d->mask)
val |= d->mask; /* falling */
else
val &= ~d->mask; /* rising */
break;
}
default:
spin_unlock_irqrestore(&info->irq_lock, flags);
return -EINVAL;
......@@ -586,6 +599,40 @@ static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
return 0;
}
static int armada_37xx_edge_both_irq_swap_pol(struct armada_37xx_pinctrl *info,
u32 pin_idx)
{
u32 reg_idx = pin_idx / GPIO_PER_REG;
u32 bit_num = pin_idx % GPIO_PER_REG;
u32 p, l, ret;
unsigned long flags;
regmap_read(info->regmap, INPUT_VAL + 4*reg_idx, &l);
spin_lock_irqsave(&info->irq_lock, flags);
p = readl(info->base + IRQ_POL + 4 * reg_idx);
if ((p ^ l) & (1 << bit_num)) {
/*
* For the gpios which are used for both-edge irqs, when their
* interrupts happen, their input levels are changed,
* yet their interrupt polarities are kept in old values, we
* should synchronize their interrupt polarities; for example,
* at first a gpio's input level is low and its interrupt
* polarity control is "Detect rising edge", then the gpio has
* a interrupt , its level turns to high, we should change its
* polarity control to "Detect falling edge" correspondingly.
*/
p ^= 1 << bit_num;
writel(p, info->base + IRQ_POL + 4 * reg_idx);
ret = 0;
} else {
/* Spurious irq */
ret = -1;
}
spin_unlock_irqrestore(&info->irq_lock, flags);
return ret;
}
static void armada_37xx_irq_handler(struct irq_desc *desc)
{
......@@ -609,6 +656,23 @@ static void armada_37xx_irq_handler(struct irq_desc *desc)
u32 hwirq = ffs(status) - 1;
u32 virq = irq_find_mapping(d, hwirq +
i * GPIO_PER_REG);
u32 t = irq_get_trigger_type(virq);
if ((t & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
/* Swap polarity (race with GPIO line) */
if (armada_37xx_edge_both_irq_swap_pol(info,
hwirq + i * GPIO_PER_REG)) {
/*
* For spurious irq, which gpio level
* is not as expected after incoming
* edge, just ack the gpio irq.
*/
writel(1 << hwirq,
info->base +
IRQ_STATUS + 4 * i);
continue;
}
}
generic_handle_irq(virq);
......
......@@ -49,6 +49,7 @@ static const struct pin_config_item conf_items[] = {
PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector", true),
PCONFDUMP(PIN_CONFIG_SLEEP_HARDWARE_STATE, "sleep hardware state", NULL, false),
PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL, true),
PCONFDUMP(PIN_CONFIG_SKEW_DELAY, "skew delay", NULL, true),
};
static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
......@@ -181,6 +182,7 @@ static const struct pinconf_generic_params dt_params[] = {
{ "power-source", PIN_CONFIG_POWER_SOURCE, 0 },
{ "sleep-hardware-state", PIN_CONFIG_SLEEP_HARDWARE_STATE, 0 },
{ "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
{ "skew-delay", PIN_CONFIG_SKEW_DELAY, 0 },
};
/**
......
......@@ -753,7 +753,7 @@ static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin)
return false;
}
int amd_gpio_suspend(struct device *dev)
static int amd_gpio_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct amd_gpio *gpio_dev = platform_get_drvdata(pdev);
......@@ -772,7 +772,7 @@ int amd_gpio_suspend(struct device *dev)
return 0;
}
int amd_gpio_resume(struct device *dev)
static int amd_gpio_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct amd_gpio *gpio_dev = platform_get_drvdata(pdev);
......
此差异已折叠。
......@@ -717,7 +717,7 @@ static const struct of_device_id ingenic_pinctrl_of_match[] = {
{},
};
int ingenic_pinctrl_probe(struct platform_device *pdev)
static int ingenic_pinctrl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ingenic_pinctrl *jzpc;
......
......@@ -420,11 +420,9 @@ static int max77620_pinconf_set(struct pinctrl_dev *pctldev,
MAX77620_REG_GPIO0 + pin,
MAX77620_CNFG_GPIO_DRV_MASK,
val);
if (ret < 0) {
dev_err(dev, "Reg 0x%02x update failed %d\n",
MAX77620_REG_GPIO0 + pin, ret);
return ret;
}
if (ret)
goto report_update_failure;
mpci->pin_info[pin].drv_type = val ?
MAX77620_PIN_PP_DRV : MAX77620_PIN_OD_DRV;
break;
......@@ -435,11 +433,9 @@ static int max77620_pinconf_set(struct pinctrl_dev *pctldev,
MAX77620_REG_GPIO0 + pin,
MAX77620_CNFG_GPIO_DRV_MASK,
val);
if (ret < 0) {
dev_err(dev, "Reg 0x%02x update failed %d\n",
MAX77620_REG_GPIO0 + pin, ret);
return ret;
}
if (ret)
goto report_update_failure;
mpci->pin_info[pin].drv_type = val ?
MAX77620_PIN_PP_DRV : MAX77620_PIN_OD_DRV;
break;
......@@ -536,6 +532,11 @@ static int max77620_pinconf_set(struct pinctrl_dev *pctldev,
}
return 0;
report_update_failure:
dev_err(dev, "Reg 0x%02x update failed %d\n",
MAX77620_REG_GPIO0 + pin, ret);
return ret;
}
static const struct pinconf_ops max77620_pinconf_ops = {
......
......@@ -25,6 +25,7 @@
#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
......@@ -278,8 +279,7 @@ static int mcp_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
{
struct mcp23s08 *mcp = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param;
u32 arg, mask;
u16 val;
u32 arg;
int ret = 0;
int i;
......@@ -289,8 +289,6 @@ static int mcp_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
switch (param) {
case PIN_CONFIG_BIAS_PULL_UP:
val = arg ? 0xFFFF : 0x0000;
mask = BIT(pin);
ret = mcp_set_bit(mcp, MCP_GPPU, pin, arg);
break;
default:
......@@ -837,6 +835,13 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
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:
......@@ -883,7 +888,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
if (mirror)
status |= IOCON_MIRROR | (IOCON_MIRROR << 8);
if (type == MCP_TYPE_S18)
if (type == MCP_TYPE_S18 || type == MCP_TYPE_018)
status |= IOCON_INTCC | (IOCON_INTCC << 8);
ret = mcp_write(mcp, MCP_IOCON, status);
......@@ -964,6 +969,10 @@ static const struct of_device_id mcp23s08_i2c_of_match[] = {
.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",
......@@ -1013,6 +1022,7 @@ static int mcp230xx_probe(struct i2c_client *client,
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);
......
......@@ -884,6 +884,24 @@ static struct rockchip_mux_route_data rk3228_mux_route_data[] = {
},
};
static struct rockchip_mux_route_data rk3288_mux_route_data[] = {
{
/* edphdmi_cecinoutt1 */
.bank_num = 7,
.pin = 16,
.func = 2,
.route_offset = 0x264,
.route_val = BIT(16 + 12) | BIT(12),
}, {
/* edphdmi_cecinout */
.bank_num = 7,
.pin = 23,
.func = 4,
.route_offset = 0x264,
.route_val = BIT(16 + 12),
},
};
static struct rockchip_mux_route_data rk3328_mux_route_data[] = {
{
/* uart2dbg_rxm0 */
......@@ -900,12 +918,19 @@ static struct rockchip_mux_route_data rk3328_mux_route_data[] = {
.route_offset = 0x50,
.route_val = BIT(16) | BIT(16 + 1) | BIT(0),
}, {
/* gmac-m1-optimized_rxd0 */
/* gmac-m1_rxd0 */
.bank_num = 1,
.pin = 11,
.func = 2,
.route_offset = 0x50,
.route_val = BIT(16 + 2) | BIT(16 + 10) | BIT(2) | BIT(10),
.route_val = BIT(16 + 2) | BIT(2),
}, {
/* gmac-m1-optimized_rxd3 */
.bank_num = 1,
.pin = 14,
.func = 2,
.route_offset = 0x50,
.route_val = BIT(16 + 10) | BIT(10),
}, {
/* pdm_sdi0m0 */
.bank_num = 2,
......@@ -3391,6 +3416,8 @@ static struct rockchip_pin_ctrl rk3288_pin_ctrl = {
.type = RK3288,
.grf_mux_offset = 0x0,
.pmu_mux_offset = 0x84,
.iomux_routes = rk3288_mux_route_data,
.niomux_routes = ARRAY_SIZE(rk3288_mux_route_data),
.pull_calc_reg = rk3288_calc_pull_reg_and_bit,
.drv_calc_reg = rk3288_calc_drv_reg_and_bit,
};
......@@ -3456,8 +3483,8 @@ static struct rockchip_pin_bank rk3399_pin_banks[] = {
DRV_TYPE_IO_1V8_ONLY,
DRV_TYPE_IO_DEFAULT,
DRV_TYPE_IO_DEFAULT,
0x0,
0x8,
0x80,
0x88,
-1,
-1,
PULL_TYPE_IO_1V8_ONLY,
......@@ -3473,10 +3500,10 @@ static struct rockchip_pin_bank rk3399_pin_banks[] = {
DRV_TYPE_IO_1V8_OR_3V0,
DRV_TYPE_IO_1V8_OR_3V0,
DRV_TYPE_IO_1V8_OR_3V0,
0x20,
0x28,
0x30,
0x38
0xa0,
0xa8,
0xb0,
0xb8
),
PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0,
DRV_TYPE_IO_1V8_OR_3V0,
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册