提交 20d5ba49 编写于 作者: L Linus Torvalds

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

Pull pinctrl updates from Linus Walleij:
 "Bulk pin control changes for the v4.10 kernel cycle:

  No core changes this time. Mainly gradual improvement and
  feature growth in the drivers.

  New drivers:

   - New driver for TI DA850/OMAP-L138/AM18XX pinconf

   - The SX150x was moved over from the GPIO subsystem and reimagined as
     a pin control driver with GPIO support in a joint effort by three
     independent users of this hardware. The result was amazingly good!

   - New subdriver for the Oxnas OX820

  Improvements:

   - The sunxi driver now supports the generic pin control bindings
     rather than the sunxi-specific. Add debouncing support to the
     driver.

   - Simplifications in pinctrl-single adding a generic parser.

   - Two downstream fixes and move the Raspberry Pi BCM2835 over to use
     the generic GPIOLIB_IRQCHIP"

* tag 'pinctrl-v4.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (92 commits)
  pinctrl: sx150x: use new nested IRQ infrastructure
  pinctrl: sx150x: handle missing 'advanced' reg in sx1504 and sx1505
  pinctrl: sx150x: rename 'reg_advance' to 'reg_advanced'
  pinctrl: sx150x: access the correct bits in the 4-bit regs of sx150[147]
  pinctrl: mt8173: set GPIO16 to usb iddig mode
  pinctrl: bcm2835: switch to GPIOLIB_IRQCHIP
  pinctrl: New driver for TI DA850/OMAP-L138/AM18XX pinconf
  devicetree: bindings: pinctrl: Add binding for ti,da850-pupd
  Documentation: pinctrl: palmas: Add ti,palmas-powerhold-override property definition
  pinctrl: intel: set default handler to be handle_bad_irq()
  pinctrl: sx150x: add support for sx1501, sx1504, sx1505 and sx1507
  pinctrl: sx150x: sort chips by part number
  pinctrl: sx150x: use correct registers for reg_sense (sx1502 and sx1508)
  pinctrl: imx: fix imx_pinctrl_desc initialization
  pinctrl: sx150x: support setting multiple pins at once
  pinctrl: sx150x: various spelling fixes and some white-space cleanup
  pinctrl: mediatek: use builtin_platform_driver
  pinctrl: stm32: use builtin_platform_driver
  pinctrl: sunxi: Testing the wrong variable
  pinctrl: nomadik: split up and comments MC0 pins
  ...
......@@ -3,7 +3,7 @@
Please refer to gpio.txt for generic information regarding GPIO bindings.
Required properties:
- compatible: "oxsemi,ox810se-gpio"
- compatible: "oxsemi,ox810se-gpio" or "oxsemi,ox820-gpio"
- reg: Base address and length for the device.
- interrupts: The port interrupt shared by all pins.
- gpio-controller: Marks the port as GPIO controller.
......
......@@ -28,6 +28,20 @@ Required properties:
- reg: Should contain the register physical address and length for the
pin controller.
- clocks: phandle to the clocks feeding the pin controller:
- "apb": the gated APB parent clock
- "hosc": the high frequency oscillator in the system
- "losc": the low frequency oscillator in the system
Note: For backward compatibility reasons, the hosc and losc clocks are only
required if you need to use the optional input-debounce property. Any new
device tree should set them.
Optional properties:
- input-debounce: Array of debouncing periods in microseconds. One period per
irq bank found in the controller. 0 if no setup required.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices.
......@@ -37,6 +51,22 @@ pins it needs, and how they should be configured, with regard to muxer
configuration, drive strength and pullups. If one of these options is
not set, its actual value will be unspecified.
This driver supports the generic pin multiplexing and configuration
bindings. For details on each properties, you can refer to
./pinctrl-bindings.txt.
Required sub-node properties:
- pins
- function
Optional sub-node properties:
- bias-disable
- bias-pull-up
- bias-pull-down
- drive-strength
*** Deprecated pin configuration and multiplexing binding
Required subnode-properties:
- allwinner,pins: List of strings containing the pin name.
......
......@@ -98,6 +98,8 @@ DRIVE_STRENGTH (3 << 5): indicate the drive strength of the pin using the
01 - Low
10 - Medium
11 - High
OUTPUT (1 << 7): indicate this pin need to be configured as an output.
OUTPUT_VAL (1 << 8): output val (1 = high, 0 = low)
DEBOUNCE (1 << 16): indicate this pin needs debounce.
DEBOUNCE_VAL (0x3fff << 17): debounce value.
......
......@@ -7,6 +7,8 @@ Required properties for the root node:
"amlogic,meson8b-aobus-pinctrl"
"amlogic,meson-gxbb-periphs-pinctrl"
"amlogic,meson-gxbb-aobus-pinctrl"
"amlogic,meson-gxl-periphs-pinctrl"
"amlogic,meson-gxl-aobus-pinctrl"
- reg: address and size of registers controlling irq functionality
=== GPIO sub-nodes ===
......
......@@ -9,7 +9,7 @@ used for a specific device or function. This node represents configurations of
pins, optional function, and optional mux related configuration.
Required properties for pin controller node:
- compatible: "oxsemi,ox810se-pinctrl"
- compatible: "oxsemi,ox810se-pinctrl" or "oxsemi,ox820-pinctrl"
- oxsemi,sys-ctrl: a phandle to the system controller syscon node
Required properties for pin configuration sub-nodes:
......
......@@ -97,6 +97,11 @@ For example:
};
== Pin controller devices ==
Required properties: See the pin controller driver specific documentation
Optional properties:
#pinctrl-cells: Number of pin control cells in addition to the index within the
pin controller device instance
Pin controller devices should contain the pin configuration nodes that client
devices reference.
......@@ -119,7 +124,8 @@ For example:
The contents of each of those pin configuration child nodes is defined
entirely by the binding for the individual pin controller device. There
exists no common standard for this content.
exists no common standard for this content. The pinctrl framework only
provides generic helper bindings that the pin controller driver can use.
The pin configuration nodes need not be direct children of the pin controller
device; they may be grandchildren, for example. Whether this is legal, and
......@@ -156,6 +162,42 @@ state_2_node_a {
pins = "mfio29", "mfio30";
};
Optionally an altenative binding can be used if more suitable depending on the
pin controller hardware. For hardaware where there is a large number of identical
pin controller instances, naming each pin and function can easily become
unmaintainable. This is especially the case if the same controller is used for
different pins and functions depending on the SoC revision and packaging.
For cases like this, the pin controller driver may use pinctrl-pin-array helper
binding with a hardware based index and a number of pin configuration values:
pincontroller {
... /* Standard DT properties for the device itself elided */
#pinctrl-cells = <2>;
state_0_node_a {
pinctrl-pin-array = <
0 A_DELAY_PS(0) G_DELAY_PS(120)
4 A_DELAY_PS(0) G_DELAY_PS(360)
...
>;
};
...
};
Above #pinctrl-cells specifies the number of value cells in addition to the
index of the registers. This is similar to the interrupts-extended binding with
one exception. There is no need to specify the phandle for each entry as that
is already known as the defined pins are always children of the pin controller
node. Further having the phandle pointing to another pin controller would not
currently work as the pinctrl framework uses named modes to group pins for each
pin control device.
The index for pinctrl-pin-array must relate to the hardware for the pinctrl
registers, and must not be a virtual index of pin instances. The reason for
this is to avoid mapping of the index in the dts files and the pin controller
driver as it can change.
== Generic pin configuration node content ==
Many data items that are represented in a pin configuration node are common
......
......@@ -35,6 +35,15 @@ Optional properties:
- ti,palmas-enable-dvfs2: Enable DVFS2. Configure pins for DVFS2 mode.
Selection primary or secondary function associated to GPADC_START
and SYSEN2 pin/pad for DVFS2 interface
- ti,palmas-override-powerhold: This is applicable for PMICs for which
GPIO7 is configured in POWERHOLD mode which has higher priority
over DEV_ON bit and keeps the PMIC supplies on even after the DEV_ON
bit is turned off. This property enables driver to over ride the
POWERHOLD value to GPIO7 so as to turn off the PMIC in power off
scenarios. So for GPIO7 if ti,palmas-override-powerhold is set
then the GPIO_7 field should never be muxed to anything else.
It should be set to POWERHOLD by default and only in case of
power off scenarios the driver will over ride the mux value.
This binding uses the following generic properties as defined in
pinctrl-bindings.txt:
......
......@@ -6,10 +6,15 @@ pin controller, GPIO, and interrupt bindings.
Required properties:
- compatible: should be one of :
"semtech,sx1501q",
"semtech,sx1502q",
"semtech,sx1503q",
"semtech,sx1504q",
"semtech,sx1505q",
"semtech,sx1506q",
"semtech,sx1507q",
"semtech,sx1508q",
"semtech,sx1509q",
"semtech,sx1502q".
"semtech,sx1509q".
- reg: The I2C slave address for this device.
......@@ -27,7 +32,7 @@ Optional properties :
- interrupt-controller: Marks the device as a interrupt controller.
- semtech,probe-reset: Will trigger a reset of the GPIO expander on probe,
only for sx1508q and sx1509q
only for sx1507q, sx1508q and sx1509q
The GPIO expander can optionally be used as an interrupt controller, in
which case it uses the default two cell specifier.
......@@ -42,7 +47,7 @@ Optional properties for pin configuration sub-nodes:
- bias-pull-down: pull down the pin, except the OSCIO pin
- bias-pull-pin-default: use pin-default pull state, except the OSCIO pin
- drive-push-pull: drive actively high and low
- drive-open-drain: drive with open drain only for sx1508q and sx1509q and except the OSCIO pin
- drive-open-drain: drive with open drain only for sx1507q, sx1508q and sx1509q and except the OSCIO pin
- output-low: set the pin to output mode with low level
- output-high: set the pin to output mode with high level
......
Qualcomm MSM8994 TLMM block
This binding describes the Top Level Mode Multiplexer block found in the
MSM8994 platform.
- compatible:
Usage: required
Value type: <string>
Definition: Should contain one of:
"qcom,msm8992-pinctrl",
"qcom,msm8994-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-gpio145
Supports mux, bias and drive-strength
sdc1_clk, sdc1_cmd, sdc1_data sdc1_rclk, sdc2_clk,
sdc2_cmd, sdc2_data
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:
audio_ref_clk, 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_spi1_cs1, blsp_spi1_cs2, blsp_spi1_cs3,
blsp_spi2, blsp_spi2_cs1, blsp_spi2_cs2, blsp_spi2_cs3, blsp_spi3,
blsp_spi4, blsp_spi5, blsp_spi6, blsp_spi7, blsp_spi8, blsp_spi9,
blsp_spi10, blsp_spi10_cs1, blsp_spi10_cs2, blsp_spi10_cs3, blsp_spi11,
blsp_spi12, blsp_uart1, blsp_uart2, blsp_uart3, blsp_uart4, blsp_uart5,
blsp_uart6, blsp_uart7, blsp_uart8, blsp_uart9, blsp_uart10, blsp_uart11,
blsp_uart12, blsp_uim1, blsp_uim2, blsp_uim3, blsp_uim4, blsp_uim5,
blsp_uim6, blsp_uim7, blsp_uim8, blsp_uim9, blsp_uim10, blsp_uim11,
blsp_uim12, blsp11_i2c_scl_b, blsp11_i2c_sda_b, blsp11_uart_rx_b,
blsp11_uart_tx_b, cam_mclk0, cam_mclk1, cam_mclk2, cam_mclk3,
cci_async_in0, cci_async_in1, cci_async_in2, cci_i2c0, cci_i2c1,
cci_timer0, cci_timer1, cci_timer2, cci_timer3, cci_timer4,
gcc_gp1_clk_a, gcc_gp1_clk_b, gcc_gp2_clk_a, gcc_gp2_clk_b, gcc_gp3_clk_a,
gcc_gp3_clk_b, gp_mn, gp_pdm0, gp_pdm1, gp_pdm2, gp0_clk,
gp1_clk, gps_tx, gsm_tx, hdmi_cec, hdmi_ddc, hdmi_hpd, hdmi_rcv,
mdp_vsync, mss_lte, nav_pps, nav_tsync, qdss_cti_trig_in_a,
qdss_cti_trig_in_b, qdss_cti_trig_in_c, qdss_cti_trig_in_d,
qdss_cti_trig_out_a, qdss_cti_trig_out_b, qdss_cti_trig_out_c,
qdss_cti_trig_out_d, qdss_traceclk_a, qdss_traceclk_b, qdss_tracectl_a,
qdss_tracectl_b, qdss_tracedata_a, qdss_tracedata_b, qua_mi2s, pci_e0,
pci_e1, pri_mi2s, sdc4, sec_mi2s, slimbus, spkr_i2s, ter_mi2s, tsif1,
tsif2, uim_batt_alarm, uim1, uim2, uim3, uim4, gpio
- 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:
msmgpio: pinctrl@fd510000 {
compatible = "qcom,msm8994-pinctrl";
reg = <0xfd510000 0x4000>;
interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
blsp1_uart2_default: blsp1_uart2_default {
pinmux {
pins = "gpio4", "gpio5";
function = "blsp_uart2";
};
pinconf {
pins = "gpio4", "gpio5";
drive-strength = <16>;
bias-disable;
};
};
};
......@@ -19,10 +19,11 @@ The pins are grouped into up to 5 individual pin banks which need to be
defined as gpio sub-nodes of the pinmux controller.
Required properties for iomux controller:
- compatible: one of "rockchip,rk2928-pinctrl", "rockchip,rk3066a-pinctrl"
"rockchip,rk3066b-pinctrl", "rockchip,rk3188-pinctrl"
"rockchip,rk3228-pinctrl", "rockchip,rk3288-pinctrl"
"rockchip,rk3368-pinctrl", "rockchip,rk3399-pinctrl"
- compatible: one of "rockchip,rk1108-pinctrl", "rockchip,rk2928-pinctrl"
"rockchip,rk3066a-pinctrl", "rockchip,rk3066b-pinctrl"
"rockchip,rk3188-pinctrl", "rockchip,rk3228-pinctrl"
"rockchip,rk3288-pinctrl", "rockchip,rk3368-pinctrl"
"rockchip,rk3399-pinctrl"
- rockchip,grf: phandle referencing a syscon providing the
"general register files"
......
......@@ -19,11 +19,30 @@ Required Properties:
- "samsung,exynos5260-pinctrl": for Exynos5260 compatible pin-controller.
- "samsung,exynos5410-pinctrl": for Exynos5410 compatible pin-controller.
- "samsung,exynos5420-pinctrl": for Exynos5420 compatible pin-controller.
- "samsung,exynos5433-pinctrl": for Exynos5433 compatible pin-controller.
- "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller.
- reg: Base address of the pin controller hardware module and length of
the address space it occupies.
- reg: Second base address of the pin controller if the specific registers
of the pin controller are separated into the different base address.
Eg: GPF[1-5] of Exynos5433 are separated into the two base address.
- First base address is for GPAx and GPF[1-5] external interrupt
registers.
- Second base address is for GPF[1-5] pinctrl registers.
pinctrl_0: pinctrl@10580000 {
compatible = "samsung,exynos5433-pinctrl";
reg = <0x10580000 0x1a20>, <0x11090000 0x100>;
wakeup-interrupt-controller {
compatible = "samsung,exynos7-wakeup-eint";
interrupts = <0 16 0>;
};
};
- Pin banks as child nodes: Pin banks of the controller are represented by child
nodes of the controller node. Bank name is taken from name of the node. Each
bank node must contain following properties:
......
* Pin configuration for TI DA850/OMAP-L138/AM18x
These SoCs have a separate controller for setting bias (internal pullup/down).
Bias can only be selected for groups rather than individual pins.
Required Properties:
- compatible: Must be "ti,da850-pupd"
- reg: Base address and length of the memory resource used by the pullup/down
controller hardware module.
The controller node also acts as a container for pin group configuration nodes.
The names of these groups are ignored.
Pin Group Node Properties:
- groups: An array of strings, each string containing the name of a pin group.
Valid names are "cp0".."cp31".
The pin configuration parameters use the generic pinconf bindings defined in
pinctrl-bindings.txt in this directory. The supported parameters are
bias-disable, bias-pull-up, bias-pull-down.
Example
-------
In common dtsi file:
pinconf: pin-controller@22c00c {
compatible = "ti,da850-pupd";
reg = <0x22c00c 0x8>;
};
In board-specific file:
&pinconf {
pinctrl-0 = <&pinconf_bias_groups>;
pinctrl-names = "default";
pinconf_bias_groups: bias-groups {
pull-up {
groups = "cp30", "cp31";
bias-pull-up;
};
pull-down {
groups = "cp29", "cp28";
bias-pull-down;
};
disable {
groups = "cp27", "cp26";
bias-disable;
};
};
};
......@@ -93,6 +93,15 @@ config PINCTRL_AMD
Requires ACPI/FDT device enumeration code to set up a platform
device.
config PINCTRL_DA850_PUPD
tristate "TI DA850/OMAP-L138/AM18XX pullup/pulldown groups"
depends on OF && (ARCH_DAVINCI_DA850 || COMPILE_TEST)
select PINCONF
select GENERIC_PINCONF
help
Driver for TI DA850/OMAP-L138/AM18XX pinconf. Used to control
pullup/pulldown pin groups.
config PINCTRL_DIGICOLOR
bool
depends on OF && (ARCH_DIGICOLOR || COMPILE_TEST)
......@@ -171,6 +180,7 @@ config PINCTRL_SX150X
select PINCONF
select GENERIC_PINCONF
select GPIOLIB_IRQCHIP
select REGMAP
help
Say yes here to provide support for Semtech SX150x-series I2C
GPIO expanders as pinctrl module.
......@@ -223,7 +233,7 @@ config PINCTRL_COH901
config PINCTRL_MAX77620
tristate "MAX77620/MAX20024 Pincontrol support"
depends on MFD_MAX77620
depends on MFD_MAX77620 && OF
select PINMUX
select GENERIC_PINCONF
help
......
......@@ -14,6 +14,7 @@ obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o
obj-$(CONFIG_PINCTRL_DA850_PUPD) += pinctrl-da850-pupd.o
obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_MAX77620) += pinctrl-max77620.o
......
......@@ -20,6 +20,7 @@ config PINCTRL_BCM2835
bool
select PINMUX
select PINCONF
select GPIOLIB_IRQCHIP
config PINCTRL_IPROC_GPIO
bool "Broadcom iProc GPIO (with PINCONF) driver"
......
......@@ -24,11 +24,9 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqdesc.h>
#include <linux/irqdomain.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of.h>
......@@ -47,6 +45,7 @@
#define MODULE_NAME "pinctrl-bcm2835"
#define BCM2835_NUM_GPIOS 54
#define BCM2835_NUM_BANKS 2
#define BCM2835_NUM_IRQS 3
#define BCM2835_PIN_BITMAP_SZ \
DIV_ROUND_UP(BCM2835_NUM_GPIOS, sizeof(unsigned long) * 8)
......@@ -86,31 +85,23 @@ enum bcm2835_pinconf_pull {
#define BCM2835_PINCONF_UNPACK_PARAM(_conf_) ((_conf_) >> 16)
#define BCM2835_PINCONF_UNPACK_ARG(_conf_) ((_conf_) & 0xffff)
struct bcm2835_gpio_irqdata {
struct bcm2835_pinctrl *pc;
int bank;
};
struct bcm2835_pinctrl {
struct device *dev;
void __iomem *base;
int irq[BCM2835_NUM_BANKS];
int irq[BCM2835_NUM_IRQS];
/* note: locking assumes each bank will have its own unsigned long */
unsigned long enabled_irq_map[BCM2835_NUM_BANKS];
unsigned int irq_type[BCM2835_NUM_GPIOS];
struct pinctrl_dev *pctl_dev;
struct irq_domain *irq_domain;
struct gpio_chip gpio_chip;
struct pinctrl_gpio_range gpio_range;
struct bcm2835_gpio_irqdata irq_data[BCM2835_NUM_BANKS];
int irq_group[BCM2835_NUM_IRQS];
spinlock_t irq_lock[BCM2835_NUM_BANKS];
};
static struct lock_class_key gpio_lock_class;
/* pins are just named GPIO0..GPIO53 */
#define BCM2835_GPIO_PIN(a) PINCTRL_PIN(a, "gpio" #a)
static struct pinctrl_pin_desc bcm2835_gpio_pins[] = {
......@@ -368,13 +359,6 @@ static int bcm2835_gpio_direction_output(struct gpio_chip *chip,
return pinctrl_gpio_direction_output(chip->base + offset);
}
static int bcm2835_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
return irq_linear_revmap(pc->irq_domain, offset);
}
static struct gpio_chip bcm2835_gpio_chip = {
.label = MODULE_NAME,
.owner = THIS_MODULE,
......@@ -385,31 +369,67 @@ static struct gpio_chip bcm2835_gpio_chip = {
.get_direction = bcm2835_gpio_get_direction,
.get = bcm2835_gpio_get,
.set = bcm2835_gpio_set,
.to_irq = bcm2835_gpio_to_irq,
.base = -1,
.ngpio = BCM2835_NUM_GPIOS,
.can_sleep = false,
};
static irqreturn_t bcm2835_gpio_irq_handler(int irq, void *dev_id)
static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc,
unsigned int bank, u32 mask)
{
struct bcm2835_gpio_irqdata *irqdata = dev_id;
struct bcm2835_pinctrl *pc = irqdata->pc;
int bank = irqdata->bank;
unsigned long events;
unsigned offset;
unsigned gpio;
unsigned int type;
events = bcm2835_gpio_rd(pc, GPEDS0 + bank * 4);
events &= mask;
events &= pc->enabled_irq_map[bank];
for_each_set_bit(offset, &events, 32) {
gpio = (32 * bank) + offset;
/* FIXME: no clue why the code looks up the type here */
type = pc->irq_type[gpio];
generic_handle_irq(irq_linear_revmap(pc->irq_domain, gpio));
generic_handle_irq(irq_linear_revmap(pc->gpio_chip.irqdomain,
gpio));
}
return events ? IRQ_HANDLED : IRQ_NONE;
}
static void bcm2835_gpio_irq_handler(struct irq_desc *desc)
{
struct gpio_chip *chip = irq_desc_get_handler_data(desc);
struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
struct irq_chip *host_chip = irq_desc_get_chip(desc);
int irq = irq_desc_get_irq(desc);
int group;
int i;
for (i = 0; i < ARRAY_SIZE(pc->irq); i++) {
if (pc->irq[i] == irq) {
group = pc->irq_group[i];
break;
}
}
/* This should not happen, every IRQ has a bank */
if (i == ARRAY_SIZE(pc->irq))
BUG();
chained_irq_enter(host_chip, desc);
switch (group) {
case 0: /* IRQ0 covers GPIOs 0-27 */
bcm2835_gpio_irq_handle_bank(pc, 0, 0x0fffffff);
break;
case 1: /* IRQ1 covers GPIOs 28-45 */
bcm2835_gpio_irq_handle_bank(pc, 0, 0xf0000000);
bcm2835_gpio_irq_handle_bank(pc, 1, 0x00003fff);
break;
case 2: /* IRQ2 covers GPIOs 46-53 */
bcm2835_gpio_irq_handle_bank(pc, 1, 0x003fc000);
break;
}
chained_irq_exit(host_chip, desc);
}
static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc,
......@@ -455,7 +475,8 @@ static void bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc,
static void bcm2835_gpio_irq_enable(struct irq_data *data)
{
struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data);
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
unsigned gpio = irqd_to_hwirq(data);
unsigned offset = GPIO_REG_SHIFT(gpio);
unsigned bank = GPIO_REG_OFFSET(gpio);
......@@ -469,7 +490,8 @@ static void bcm2835_gpio_irq_enable(struct irq_data *data)
static void bcm2835_gpio_irq_disable(struct irq_data *data)
{
struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data);
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
unsigned gpio = irqd_to_hwirq(data);
unsigned offset = GPIO_REG_SHIFT(gpio);
unsigned bank = GPIO_REG_OFFSET(gpio);
......@@ -575,7 +597,8 @@ static int __bcm2835_gpio_irq_set_type_enabled(struct bcm2835_pinctrl *pc,
static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type)
{
struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data);
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
unsigned gpio = irqd_to_hwirq(data);
unsigned offset = GPIO_REG_SHIFT(gpio);
unsigned bank = GPIO_REG_OFFSET(gpio);
......@@ -601,7 +624,8 @@ static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type)
static void bcm2835_gpio_irq_ack(struct irq_data *data)
{
struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data);
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
unsigned gpio = irqd_to_hwirq(data);
bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
......@@ -644,10 +668,11 @@ static void bcm2835_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
unsigned offset)
{
struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
struct gpio_chip *chip = &pc->gpio_chip;
enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset);
const char *fname = bcm2835_functions[fsel];
int value = bcm2835_gpio_get_bit(pc, GPLEV0, offset);
int irq = irq_find_mapping(pc->irq_domain, offset);
int irq = irq_find_mapping(chip->irqdomain, offset);
seq_printf(s, "function %s in %s; irq %d (%s)",
fname, value ? "hi" : "lo",
......@@ -821,6 +846,16 @@ static const struct pinctrl_ops bcm2835_pctl_ops = {
.dt_free_map = bcm2835_pctl_dt_free_map,
};
static int bcm2835_pmx_free(struct pinctrl_dev *pctldev,
unsigned offset)
{
struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
/* disable by setting to GPIO_IN */
bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN);
return 0;
}
static int bcm2835_pmx_get_functions_count(struct pinctrl_dev *pctldev)
{
return BCM2835_FSEL_COUNT;
......@@ -880,6 +915,7 @@ static int bcm2835_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
}
static const struct pinmux_ops bcm2835_pmx_ops = {
.free = bcm2835_pmx_free,
.get_functions_count = bcm2835_pmx_get_functions_count,
.get_function_name = bcm2835_pmx_get_function_name,
.get_function_groups = bcm2835_pmx_get_function_groups,
......@@ -917,12 +953,14 @@ static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev,
bcm2835_gpio_wr(pc, GPPUD, arg & 3);
/*
* Docs say to wait 150 cycles, but not of what. We assume a
* 1 MHz clock here, which is pretty slow...
* BCM2835 datasheet say to wait 150 cycles, but not of what.
* But the VideoCore firmware delay for this operation
* based nearly on the same amount of VPU cycles and this clock
* runs at 250 MHz.
*/
udelay(150);
udelay(1);
bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit));
udelay(150);
udelay(1);
bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0);
} /* for each config */
......@@ -980,26 +1018,9 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
pc->gpio_chip.parent = dev;
pc->gpio_chip.of_node = np;
pc->irq_domain = irq_domain_add_linear(np, BCM2835_NUM_GPIOS,
&irq_domain_simple_ops, NULL);
if (!pc->irq_domain) {
dev_err(dev, "could not create IRQ domain\n");
return -ENOMEM;
}
for (i = 0; i < BCM2835_NUM_GPIOS; i++) {
int irq = irq_create_mapping(pc->irq_domain, i);
irq_set_lockdep_class(irq, &gpio_lock_class);
irq_set_chip_and_handler(irq, &bcm2835_gpio_irq_chip,
handle_level_irq);
irq_set_chip_data(irq, pc);
}
for (i = 0; i < BCM2835_NUM_BANKS; i++) {
unsigned long events;
unsigned offset;
int len;
char *name;
/* clear event detection flags */
bcm2835_gpio_wr(pc, GPREN0 + i * 4, 0);
......@@ -1014,24 +1035,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
for_each_set_bit(offset, &events, 32)
bcm2835_gpio_wr(pc, GPEDS0 + i * 4, BIT(offset));
pc->irq[i] = irq_of_parse_and_map(np, i);
pc->irq_data[i].pc = pc;
pc->irq_data[i].bank = i;
spin_lock_init(&pc->irq_lock[i]);
len = strlen(dev_name(pc->dev)) + 16;
name = devm_kzalloc(pc->dev, len, GFP_KERNEL);
if (!name)
return -ENOMEM;
snprintf(name, len, "%s:bank%d", dev_name(pc->dev), i);
err = devm_request_irq(dev, pc->irq[i],
bcm2835_gpio_irq_handler, IRQF_SHARED,
name, &pc->irq_data[i]);
if (err) {
dev_err(dev, "unable to request IRQ %d\n", pc->irq[i]);
return err;
}
}
err = gpiochip_add_data(&pc->gpio_chip, pc);
......@@ -1040,6 +1044,29 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
return err;
}
err = gpiochip_irqchip_add(&pc->gpio_chip, &bcm2835_gpio_irq_chip,
0, handle_level_irq, IRQ_TYPE_NONE);
if (err) {
dev_info(dev, "could not add irqchip\n");
return err;
}
for (i = 0; i < BCM2835_NUM_IRQS; i++) {
pc->irq[i] = irq_of_parse_and_map(np, i);
pc->irq_group[i] = i;
/*
* Use the same handler for all groups: this is necessary
* since we use one gpiochip to cover all lines - the
* irq handler then needs to figure out which group and
* bank that was firing the IRQ and look up the per-group
* and bank data.
*/
gpiochip_set_chained_irqchip(&pc->gpio_chip,
&bcm2835_gpio_irq_chip,
pc->irq[i],
bcm2835_gpio_irq_handler);
}
pc->pctl_dev = devm_pinctrl_register(dev, &bcm2835_pinctrl_desc, pc);
if (IS_ERR(pc->pctl_dev)) {
gpiochip_remove(&pc->gpio_chip);
......
......@@ -253,3 +253,147 @@ int pinctrl_dt_to_map(struct pinctrl *p)
pinctrl_dt_free_maps(p);
return ret;
}
/*
* For pinctrl binding, typically #pinctrl-cells is for the pin controller
* device, so either parent or grandparent. See pinctrl-bindings.txt.
*/
static int pinctrl_find_cells_size(const struct device_node *np)
{
const char *cells_name = "#pinctrl-cells";
int cells_size, error;
error = of_property_read_u32(np->parent, cells_name, &cells_size);
if (error) {
error = of_property_read_u32(np->parent->parent,
cells_name, &cells_size);
if (error)
return -ENOENT;
}
return cells_size;
}
/**
* pinctrl_get_list_and_count - Gets the list and it's cell size and number
* @np: pointer to device node with the property
* @list_name: property that contains the list
* @list: pointer for the list found
* @cells_size: pointer for the cell size found
* @nr_elements: pointer for the number of elements found
*
* Typically np is a single pinctrl entry containing the list.
*/
static int pinctrl_get_list_and_count(const struct device_node *np,
const char *list_name,
const __be32 **list,
int *cells_size,
int *nr_elements)
{
int size;
*cells_size = 0;
*nr_elements = 0;
*list = of_get_property(np, list_name, &size);
if (!*list)
return -ENOENT;
*cells_size = pinctrl_find_cells_size(np);
if (*cells_size < 0)
return -ENOENT;
/* First element is always the index within the pinctrl device */
*nr_elements = (size / sizeof(**list)) / (*cells_size + 1);
return 0;
}
/**
* pinctrl_count_index_with_args - Count number of elements in a pinctrl entry
* @np: pointer to device node with the property
* @list_name: property that contains the list
*
* Counts the number of elements in a pinctrl array consisting of an index
* within the controller and a number of u32 entries specified for each
* entry. Note that device_node is always for the parent pin controller device.
*/
int pinctrl_count_index_with_args(const struct device_node *np,
const char *list_name)
{
const __be32 *list;
int size, nr_cells, error;
error = pinctrl_get_list_and_count(np, list_name, &list,
&nr_cells, &size);
if (error)
return error;
return size;
}
EXPORT_SYMBOL_GPL(pinctrl_count_index_with_args);
/**
* pinctrl_copy_args - Populates of_phandle_args based on index
* @np: pointer to device node with the property
* @list: pointer to a list with the elements
* @index: entry within the list of elements
* @nr_cells: number of cells in the list
* @nr_elem: number of elements for each entry in the list
* @out_args: returned values
*
* Populates the of_phandle_args based on the index in the list.
*/
static int pinctrl_copy_args(const struct device_node *np,
const __be32 *list,
int index, int nr_cells, int nr_elem,
struct of_phandle_args *out_args)
{
int i;
memset(out_args, 0, sizeof(*out_args));
out_args->np = (struct device_node *)np;
out_args->args_count = nr_cells + 1;
if (index >= nr_elem)
return -EINVAL;
list += index * (nr_cells + 1);
for (i = 0; i < nr_cells + 1; i++)
out_args->args[i] = be32_to_cpup(list++);
return 0;
}
/**
* pinctrl_parse_index_with_args - Find a node pointed by index in a list
* @np: pointer to device node with the property
* @list_name: property that contains the list
* @index: index within the list
* @out_arts: entries in the list pointed by index
*
* Finds the selected element in a pinctrl array consisting of an index
* within the controller and a number of u32 entries specified for each
* entry. Note that device_node is always for the parent pin controller device.
*/
int pinctrl_parse_index_with_args(const struct device_node *np,
const char *list_name, int index,
struct of_phandle_args *out_args)
{
const __be32 *list;
int nr_elem, nr_cells, error;
error = pinctrl_get_list_and_count(np, list_name, &list,
&nr_cells, &nr_elem);
if (error || !nr_cells)
return error;
error = pinctrl_copy_args(np, list, index, nr_cells, nr_elem,
out_args);
if (error)
return error;
return 0;
}
EXPORT_SYMBOL_GPL(pinctrl_parse_index_with_args);
......@@ -16,11 +16,20 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
struct of_phandle_args;
#ifdef CONFIG_OF
void pinctrl_dt_free_maps(struct pinctrl *p);
int pinctrl_dt_to_map(struct pinctrl *p);
int pinctrl_count_index_with_args(const struct device_node *np,
const char *list_name);
int pinctrl_parse_index_with_args(const struct device_node *np,
const char *list_name, int index,
struct of_phandle_args *out_args);
#else
static inline int pinctrl_dt_to_map(struct pinctrl *p)
......@@ -32,4 +41,18 @@ static inline void pinctrl_dt_free_maps(struct pinctrl *p)
{
}
static inline int pinctrl_count_index_with_args(const struct device_node *np,
const char *list_name)
{
return -ENODEV;
}
static inline int
pinctrl_parse_index_with_args(const struct device_node *np,
const char *list_name, int index,
struct of_phandle_args *out_args)
{
return -ENODEV;
}
#endif
......@@ -778,10 +778,10 @@ int imx_pinctrl_probe(struct platform_device *pdev,
imx_pinctrl_desc->name = dev_name(&pdev->dev);
imx_pinctrl_desc->pins = info->pins;
imx_pinctrl_desc->npins = info->npins;
imx_pinctrl_desc->pctlops = &imx_pctrl_ops,
imx_pinctrl_desc->pmxops = &imx_pmx_ops,
imx_pinctrl_desc->confops = &imx_pinconf_ops,
imx_pinctrl_desc->owner = THIS_MODULE,
imx_pinctrl_desc->pctlops = &imx_pctrl_ops;
imx_pinctrl_desc->pmxops = &imx_pmx_ops;
imx_pinctrl_desc->confops = &imx_pinconf_ops;
imx_pinctrl_desc->owner = THIS_MODULE;
ret = imx_pinctrl_probe_dt(pdev, info);
if (ret) {
......
......@@ -1703,7 +1703,7 @@ static int byt_gpio_probe(struct byt_gpio *vg)
if (irq_rc && irq_rc->start) {
byt_gpio_irq_init_hw(vg);
ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0,
handle_simple_irq, IRQ_TYPE_NONE);
handle_bad_irq, IRQ_TYPE_NONE);
if (ret) {
dev_err(&vg->pdev->dev, "failed to add irqchip\n");
goto fail;
......
......@@ -762,7 +762,7 @@ static void chv_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
seq_printf(s, "mode %d ", mode);
}
seq_printf(s, "ctrl0 0x%08x ctrl1 0x%08x", ctrl0, ctrl1);
seq_printf(s, "0x%08x 0x%08x", ctrl0, ctrl1);
if (locked)
seq_puts(s, " [LOCKED]");
......
......@@ -911,7 +911,7 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
}
ret = gpiochip_irqchip_add(&pctrl->chip, &intel_gpio_irqchip, 0,
handle_simple_irq, IRQ_TYPE_NONE);
handle_bad_irq, IRQ_TYPE_NONE);
if (ret) {
dev_err(pctrl->dev, "failed to add irqchip\n");
goto fail;
......
......@@ -814,10 +814,51 @@ static int mrfld_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
return 0;
}
static int mrfld_config_group_get(struct pinctrl_dev *pctldev,
unsigned int group, unsigned long *config)
{
const unsigned int *pins;
unsigned int npins;
int ret;
ret = mrfld_get_group_pins(pctldev, group, &pins, &npins);
if (ret)
return ret;
ret = mrfld_config_get(pctldev, pins[0], config);
if (ret)
return ret;
return 0;
}
static int mrfld_config_group_set(struct pinctrl_dev *pctldev,
unsigned int group, unsigned long *configs,
unsigned int num_configs)
{
const unsigned int *pins;
unsigned int npins;
int i, ret;
ret = mrfld_get_group_pins(pctldev, group, &pins, &npins);
if (ret)
return ret;
for (i = 0; i < npins; i++) {
ret = mrfld_config_set(pctldev, pins[i], configs, num_configs);
if (ret)
return ret;
}
return 0;
}
static const struct pinconf_ops mrfld_pinconf_ops = {
.is_generic = true,
.pin_config_get = mrfld_config_get,
.pin_config_set = mrfld_config_set,
.pin_config_group_get = mrfld_config_group_get,
.pin_config_group_set = mrfld_config_group_set,
};
static const struct pinctrl_desc mrfld_pinctrl_desc = {
......
......@@ -64,8 +64,4 @@ static struct platform_driver mtk_pinctrl_driver = {
},
};
static int __init mtk_pinctrl_init(void)
{
return platform_driver_register(&mtk_pinctrl_driver);
}
device_initcall(mtk_pinctrl_init);
builtin_platform_driver(mtk_pinctrl_driver);
......@@ -201,7 +201,7 @@ static const struct mtk_desc_pin mtk_pins_mt8173[] = {
MTK_PIN(
PINCTRL_PIN(16, "IDDIG"),
NULL, "mt8173",
MTK_EINT_FUNCTION(0, 16),
MTK_EINT_FUNCTION(1, 16),
MTK_FUNCTION(0, "GPIO16"),
MTK_FUNCTION(1, "IDDIG"),
MTK_FUNCTION(2, "CMFLASH"),
......
obj-y += pinctrl-meson8.o pinctrl-meson8b.o pinctrl-meson-gxbb.o
obj-y += pinctrl-meson8.o pinctrl-meson8b.o
obj-y += pinctrl-meson-gxbb.o pinctrl-meson-gxl.o
obj-y += pinctrl-meson.o
/*
* Pin controller and GPIO driver for Amlogic Meson GXL.
*
* Copyright (C) 2016 Endless Mobile, Inc.
* Author: Carlo Caione <carlo@endlessm.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/>.
*/
#include <dt-bindings/gpio/meson-gxl-gpio.h>
#include "pinctrl-meson.h"
#define EE_OFF 10
static const struct pinctrl_pin_desc meson_gxl_periphs_pins[] = {
MESON_PIN(GPIOZ_0, EE_OFF),
MESON_PIN(GPIOZ_1, EE_OFF),
MESON_PIN(GPIOZ_2, EE_OFF),
MESON_PIN(GPIOZ_3, EE_OFF),
MESON_PIN(GPIOZ_4, EE_OFF),
MESON_PIN(GPIOZ_5, EE_OFF),
MESON_PIN(GPIOZ_6, EE_OFF),
MESON_PIN(GPIOZ_7, EE_OFF),
MESON_PIN(GPIOZ_8, EE_OFF),
MESON_PIN(GPIOZ_9, EE_OFF),
MESON_PIN(GPIOZ_10, EE_OFF),
MESON_PIN(GPIOZ_11, EE_OFF),
MESON_PIN(GPIOZ_12, EE_OFF),
MESON_PIN(GPIOZ_13, EE_OFF),
MESON_PIN(GPIOZ_14, EE_OFF),
MESON_PIN(GPIOZ_15, EE_OFF),
MESON_PIN(GPIOH_0, EE_OFF),
MESON_PIN(GPIOH_1, EE_OFF),
MESON_PIN(GPIOH_2, EE_OFF),
MESON_PIN(GPIOH_3, EE_OFF),
MESON_PIN(GPIOH_4, EE_OFF),
MESON_PIN(GPIOH_5, EE_OFF),
MESON_PIN(GPIOH_6, EE_OFF),
MESON_PIN(GPIOH_7, EE_OFF),
MESON_PIN(GPIOH_8, EE_OFF),
MESON_PIN(GPIOH_9, EE_OFF),
MESON_PIN(BOOT_0, EE_OFF),
MESON_PIN(BOOT_1, EE_OFF),
MESON_PIN(BOOT_2, EE_OFF),
MESON_PIN(BOOT_3, EE_OFF),
MESON_PIN(BOOT_4, EE_OFF),
MESON_PIN(BOOT_5, EE_OFF),
MESON_PIN(BOOT_6, EE_OFF),
MESON_PIN(BOOT_7, EE_OFF),
MESON_PIN(BOOT_8, EE_OFF),
MESON_PIN(BOOT_9, EE_OFF),
MESON_PIN(BOOT_10, EE_OFF),
MESON_PIN(BOOT_11, EE_OFF),
MESON_PIN(BOOT_12, EE_OFF),
MESON_PIN(BOOT_13, EE_OFF),
MESON_PIN(BOOT_14, EE_OFF),
MESON_PIN(BOOT_15, EE_OFF),
MESON_PIN(CARD_0, EE_OFF),
MESON_PIN(CARD_1, EE_OFF),
MESON_PIN(CARD_2, EE_OFF),
MESON_PIN(CARD_3, EE_OFF),
MESON_PIN(CARD_4, EE_OFF),
MESON_PIN(CARD_5, EE_OFF),
MESON_PIN(CARD_6, EE_OFF),
MESON_PIN(GPIODV_0, EE_OFF),
MESON_PIN(GPIODV_1, EE_OFF),
MESON_PIN(GPIODV_2, EE_OFF),
MESON_PIN(GPIODV_3, EE_OFF),
MESON_PIN(GPIODV_4, EE_OFF),
MESON_PIN(GPIODV_5, EE_OFF),
MESON_PIN(GPIODV_6, EE_OFF),
MESON_PIN(GPIODV_7, EE_OFF),
MESON_PIN(GPIODV_8, EE_OFF),
MESON_PIN(GPIODV_9, EE_OFF),
MESON_PIN(GPIODV_10, EE_OFF),
MESON_PIN(GPIODV_11, EE_OFF),
MESON_PIN(GPIODV_12, EE_OFF),
MESON_PIN(GPIODV_13, EE_OFF),
MESON_PIN(GPIODV_14, EE_OFF),
MESON_PIN(GPIODV_15, EE_OFF),
MESON_PIN(GPIODV_16, EE_OFF),
MESON_PIN(GPIODV_17, EE_OFF),
MESON_PIN(GPIODV_19, EE_OFF),
MESON_PIN(GPIODV_20, EE_OFF),
MESON_PIN(GPIODV_21, EE_OFF),
MESON_PIN(GPIODV_22, EE_OFF),
MESON_PIN(GPIODV_23, EE_OFF),
MESON_PIN(GPIODV_24, EE_OFF),
MESON_PIN(GPIODV_25, EE_OFF),
MESON_PIN(GPIODV_26, EE_OFF),
MESON_PIN(GPIODV_27, EE_OFF),
MESON_PIN(GPIODV_28, EE_OFF),
MESON_PIN(GPIODV_29, EE_OFF),
MESON_PIN(GPIOX_0, EE_OFF),
MESON_PIN(GPIOX_1, EE_OFF),
MESON_PIN(GPIOX_2, EE_OFF),
MESON_PIN(GPIOX_3, EE_OFF),
MESON_PIN(GPIOX_4, EE_OFF),
MESON_PIN(GPIOX_5, EE_OFF),
MESON_PIN(GPIOX_6, EE_OFF),
MESON_PIN(GPIOX_7, EE_OFF),
MESON_PIN(GPIOX_8, EE_OFF),
MESON_PIN(GPIOX_9, EE_OFF),
MESON_PIN(GPIOX_10, EE_OFF),
MESON_PIN(GPIOX_11, EE_OFF),
MESON_PIN(GPIOX_12, EE_OFF),
MESON_PIN(GPIOX_13, EE_OFF),
MESON_PIN(GPIOX_14, EE_OFF),
MESON_PIN(GPIOX_15, EE_OFF),
MESON_PIN(GPIOX_16, EE_OFF),
MESON_PIN(GPIOX_17, EE_OFF),
MESON_PIN(GPIOX_18, EE_OFF),
MESON_PIN(GPIOCLK_0, EE_OFF),
MESON_PIN(GPIOCLK_1, EE_OFF),
MESON_PIN(GPIO_TEST_N, EE_OFF),
};
static const unsigned int emmc_nand_d07_pins[] = {
PIN(BOOT_0, EE_OFF), PIN(BOOT_1, EE_OFF), PIN(BOOT_2, EE_OFF),
PIN(BOOT_3, EE_OFF), PIN(BOOT_4, EE_OFF), PIN(BOOT_5, EE_OFF),
PIN(BOOT_6, EE_OFF), PIN(BOOT_7, EE_OFF),
};
static const unsigned int emmc_clk_pins[] = { PIN(BOOT_8, EE_OFF) };
static const unsigned int emmc_cmd_pins[] = { PIN(BOOT_10, EE_OFF) };
static const unsigned int emmc_ds_pins[] = { PIN(BOOT_15, EE_OFF) };
static const unsigned int sdcard_d0_pins[] = { PIN(CARD_1, EE_OFF) };
static const unsigned int sdcard_d1_pins[] = { PIN(CARD_0, EE_OFF) };
static const unsigned int sdcard_d2_pins[] = { PIN(CARD_5, EE_OFF) };
static const unsigned int sdcard_d3_pins[] = { PIN(CARD_4, EE_OFF) };
static const unsigned int sdcard_cmd_pins[] = { PIN(CARD_3, EE_OFF) };
static const unsigned int sdcard_clk_pins[] = { PIN(CARD_2, EE_OFF) };
static const unsigned int sdio_d0_pins[] = { PIN(GPIOX_0, EE_OFF) };
static const unsigned int sdio_d1_pins[] = { PIN(GPIOX_1, EE_OFF) };
static const unsigned int sdio_d2_pins[] = { PIN(GPIOX_2, EE_OFF) };
static const unsigned int sdio_d3_pins[] = { PIN(GPIOX_3, EE_OFF) };
static const unsigned int sdio_cmd_pins[] = { PIN(GPIOX_4, EE_OFF) };
static const unsigned int sdio_clk_pins[] = { PIN(GPIOX_5, EE_OFF) };
static const unsigned int sdio_irq_pins[] = { PIN(GPIOX_7, EE_OFF) };
static const unsigned int nand_ce0_pins[] = { PIN(BOOT_8, EE_OFF) };
static const unsigned int nand_ce1_pins[] = { PIN(BOOT_9, EE_OFF) };
static const unsigned int nand_rb0_pins[] = { PIN(BOOT_10, EE_OFF) };
static const unsigned int nand_ale_pins[] = { PIN(BOOT_11, EE_OFF) };
static const unsigned int nand_cle_pins[] = { PIN(BOOT_12, EE_OFF) };
static const unsigned int nand_wen_clk_pins[] = { PIN(BOOT_13, EE_OFF) };
static const unsigned int nand_ren_wr_pins[] = { PIN(BOOT_14, EE_OFF) };
static const unsigned int nand_dqs_pins[] = { PIN(BOOT_15, EE_OFF) };
static const unsigned int uart_tx_a_pins[] = { PIN(GPIOX_12, EE_OFF) };
static const unsigned int uart_rx_a_pins[] = { PIN(GPIOX_13, EE_OFF) };
static const unsigned int uart_cts_a_pins[] = { PIN(GPIOX_14, EE_OFF) };
static const unsigned int uart_rts_a_pins[] = { PIN(GPIOX_15, EE_OFF) };
static const unsigned int uart_tx_b_pins[] = { PIN(GPIODV_24, EE_OFF) };
static const unsigned int uart_rx_b_pins[] = { PIN(GPIODV_25, EE_OFF) };
static const unsigned int uart_tx_c_pins[] = { PIN(GPIOX_8, EE_OFF) };
static const unsigned int uart_rx_c_pins[] = { PIN(GPIOX_9, EE_OFF) };
static const unsigned int i2c_sck_a_pins[] = { PIN(GPIODV_25, EE_OFF) };
static const unsigned int i2c_sda_a_pins[] = { PIN(GPIODV_24, EE_OFF) };
static const unsigned int i2c_sck_b_pins[] = { PIN(GPIODV_27, EE_OFF) };
static const unsigned int i2c_sda_b_pins[] = { PIN(GPIODV_26, EE_OFF) };
static const unsigned int i2c_sck_c_pins[] = { PIN(GPIODV_29, EE_OFF) };
static const unsigned int i2c_sda_c_pins[] = { PIN(GPIODV_28, EE_OFF) };
static const unsigned int eth_mdio_pins[] = { PIN(GPIOZ_0, EE_OFF) };
static const unsigned int eth_mdc_pins[] = { PIN(GPIOZ_1, EE_OFF) };
static const unsigned int eth_clk_rx_clk_pins[] = { PIN(GPIOZ_2, EE_OFF) };
static const unsigned int eth_rx_dv_pins[] = { PIN(GPIOZ_3, EE_OFF) };
static const unsigned int eth_rxd0_pins[] = { PIN(GPIOZ_4, EE_OFF) };
static const unsigned int eth_rxd1_pins[] = { PIN(GPIOZ_5, EE_OFF) };
static const unsigned int eth_rxd2_pins[] = { PIN(GPIOZ_6, EE_OFF) };
static const unsigned int eth_rxd3_pins[] = { PIN(GPIOZ_7, EE_OFF) };
static const unsigned int eth_rgmii_tx_clk_pins[] = { PIN(GPIOZ_8, EE_OFF) };
static const unsigned int eth_tx_en_pins[] = { PIN(GPIOZ_9, EE_OFF) };
static const unsigned int eth_txd0_pins[] = { PIN(GPIOZ_10, EE_OFF) };
static const unsigned int eth_txd1_pins[] = { PIN(GPIOZ_11, EE_OFF) };
static const unsigned int eth_txd2_pins[] = { PIN(GPIOZ_12, EE_OFF) };
static const unsigned int eth_txd3_pins[] = { PIN(GPIOZ_13, EE_OFF) };
static const unsigned int pwm_e_pins[] = { PIN(GPIOX_16, EE_OFF) };
static const struct pinctrl_pin_desc meson_gxl_aobus_pins[] = {
MESON_PIN(GPIOAO_0, 0),
MESON_PIN(GPIOAO_1, 0),
MESON_PIN(GPIOAO_2, 0),
MESON_PIN(GPIOAO_3, 0),
MESON_PIN(GPIOAO_4, 0),
MESON_PIN(GPIOAO_5, 0),
MESON_PIN(GPIOAO_6, 0),
MESON_PIN(GPIOAO_7, 0),
MESON_PIN(GPIOAO_8, 0),
MESON_PIN(GPIOAO_9, 0),
};
static const unsigned int uart_tx_ao_a_pins[] = { PIN(GPIOAO_0, 0) };
static const unsigned int uart_rx_ao_a_pins[] = { PIN(GPIOAO_1, 0) };
static const unsigned int uart_cts_ao_a_pins[] = { PIN(GPIOAO_2, 0) };
static const unsigned int uart_rts_ao_a_pins[] = { PIN(GPIOAO_3, 0) };
static const unsigned int uart_tx_ao_b_pins[] = { PIN(GPIOAO_0, 0) };
static const unsigned int uart_rx_ao_b_pins[] = { PIN(GPIOAO_1, 0),
PIN(GPIOAO_5, 0) };
static const unsigned int uart_cts_ao_b_pins[] = { PIN(GPIOAO_2, 0) };
static const unsigned int uart_rts_ao_b_pins[] = { PIN(GPIOAO_3, 0) };
static const unsigned int remote_input_ao_pins[] = {PIN(GPIOAO_7, 0) };
static struct meson_pmx_group meson_gxl_periphs_groups[] = {
GPIO_GROUP(GPIOZ_0, EE_OFF),
GPIO_GROUP(GPIOZ_1, EE_OFF),
GPIO_GROUP(GPIOZ_2, EE_OFF),
GPIO_GROUP(GPIOZ_3, EE_OFF),
GPIO_GROUP(GPIOZ_4, EE_OFF),
GPIO_GROUP(GPIOZ_5, EE_OFF),
GPIO_GROUP(GPIOZ_6, EE_OFF),
GPIO_GROUP(GPIOZ_7, EE_OFF),
GPIO_GROUP(GPIOZ_8, EE_OFF),
GPIO_GROUP(GPIOZ_9, EE_OFF),
GPIO_GROUP(GPIOZ_10, EE_OFF),
GPIO_GROUP(GPIOZ_11, EE_OFF),
GPIO_GROUP(GPIOZ_12, EE_OFF),
GPIO_GROUP(GPIOZ_13, EE_OFF),
GPIO_GROUP(GPIOZ_14, EE_OFF),
GPIO_GROUP(GPIOZ_15, EE_OFF),
GPIO_GROUP(GPIOH_0, EE_OFF),
GPIO_GROUP(GPIOH_1, EE_OFF),
GPIO_GROUP(GPIOH_2, EE_OFF),
GPIO_GROUP(GPIOH_3, EE_OFF),
GPIO_GROUP(GPIOH_4, EE_OFF),
GPIO_GROUP(GPIOH_5, EE_OFF),
GPIO_GROUP(GPIOH_6, EE_OFF),
GPIO_GROUP(GPIOH_7, EE_OFF),
GPIO_GROUP(GPIOH_8, EE_OFF),
GPIO_GROUP(GPIOH_9, EE_OFF),
GPIO_GROUP(BOOT_0, EE_OFF),
GPIO_GROUP(BOOT_1, EE_OFF),
GPIO_GROUP(BOOT_2, EE_OFF),
GPIO_GROUP(BOOT_3, EE_OFF),
GPIO_GROUP(BOOT_4, EE_OFF),
GPIO_GROUP(BOOT_5, EE_OFF),
GPIO_GROUP(BOOT_6, EE_OFF),
GPIO_GROUP(BOOT_7, EE_OFF),
GPIO_GROUP(BOOT_8, EE_OFF),
GPIO_GROUP(BOOT_9, EE_OFF),
GPIO_GROUP(BOOT_10, EE_OFF),
GPIO_GROUP(BOOT_11, EE_OFF),
GPIO_GROUP(BOOT_12, EE_OFF),
GPIO_GROUP(BOOT_13, EE_OFF),
GPIO_GROUP(BOOT_14, EE_OFF),
GPIO_GROUP(BOOT_15, EE_OFF),
GPIO_GROUP(CARD_0, EE_OFF),
GPIO_GROUP(CARD_1, EE_OFF),
GPIO_GROUP(CARD_2, EE_OFF),
GPIO_GROUP(CARD_3, EE_OFF),
GPIO_GROUP(CARD_4, EE_OFF),
GPIO_GROUP(CARD_5, EE_OFF),
GPIO_GROUP(CARD_6, EE_OFF),
GPIO_GROUP(GPIODV_0, EE_OFF),
GPIO_GROUP(GPIODV_1, EE_OFF),
GPIO_GROUP(GPIODV_2, EE_OFF),
GPIO_GROUP(GPIODV_3, EE_OFF),
GPIO_GROUP(GPIODV_4, EE_OFF),
GPIO_GROUP(GPIODV_5, EE_OFF),
GPIO_GROUP(GPIODV_6, EE_OFF),
GPIO_GROUP(GPIODV_7, EE_OFF),
GPIO_GROUP(GPIODV_8, EE_OFF),
GPIO_GROUP(GPIODV_9, EE_OFF),
GPIO_GROUP(GPIODV_10, EE_OFF),
GPIO_GROUP(GPIODV_11, EE_OFF),
GPIO_GROUP(GPIODV_12, EE_OFF),
GPIO_GROUP(GPIODV_13, EE_OFF),
GPIO_GROUP(GPIODV_14, EE_OFF),
GPIO_GROUP(GPIODV_15, EE_OFF),
GPIO_GROUP(GPIODV_16, EE_OFF),
GPIO_GROUP(GPIODV_17, EE_OFF),
GPIO_GROUP(GPIODV_19, EE_OFF),
GPIO_GROUP(GPIODV_20, EE_OFF),
GPIO_GROUP(GPIODV_21, EE_OFF),
GPIO_GROUP(GPIODV_22, EE_OFF),
GPIO_GROUP(GPIODV_23, EE_OFF),
GPIO_GROUP(GPIODV_24, EE_OFF),
GPIO_GROUP(GPIODV_25, EE_OFF),
GPIO_GROUP(GPIODV_26, EE_OFF),
GPIO_GROUP(GPIODV_27, EE_OFF),
GPIO_GROUP(GPIODV_28, EE_OFF),
GPIO_GROUP(GPIODV_29, EE_OFF),
GPIO_GROUP(GPIOX_0, EE_OFF),
GPIO_GROUP(GPIOX_1, EE_OFF),
GPIO_GROUP(GPIOX_2, EE_OFF),
GPIO_GROUP(GPIOX_3, EE_OFF),
GPIO_GROUP(GPIOX_4, EE_OFF),
GPIO_GROUP(GPIOX_5, EE_OFF),
GPIO_GROUP(GPIOX_6, EE_OFF),
GPIO_GROUP(GPIOX_7, EE_OFF),
GPIO_GROUP(GPIOX_8, EE_OFF),
GPIO_GROUP(GPIOX_9, EE_OFF),
GPIO_GROUP(GPIOX_10, EE_OFF),
GPIO_GROUP(GPIOX_11, EE_OFF),
GPIO_GROUP(GPIOX_12, EE_OFF),
GPIO_GROUP(GPIOX_13, EE_OFF),
GPIO_GROUP(GPIOX_14, EE_OFF),
GPIO_GROUP(GPIOX_15, EE_OFF),
GPIO_GROUP(GPIOX_16, EE_OFF),
GPIO_GROUP(GPIOX_17, EE_OFF),
GPIO_GROUP(GPIOX_18, EE_OFF),
GPIO_GROUP(GPIOCLK_0, EE_OFF),
GPIO_GROUP(GPIOCLK_1, EE_OFF),
GPIO_GROUP(GPIO_TEST_N, EE_OFF),
/* Bank X */
GROUP(sdio_d0, 5, 31),
GROUP(sdio_d1, 5, 30),
GROUP(sdio_d2, 5, 29),
GROUP(sdio_d3, 5, 28),
GROUP(sdio_cmd, 5, 27),
GROUP(sdio_clk, 5, 26),
GROUP(sdio_irq, 5, 24),
GROUP(uart_tx_a, 5, 19),
GROUP(uart_rx_a, 5, 18),
GROUP(uart_cts_a, 5, 17),
GROUP(uart_rts_a, 5, 16),
GROUP(uart_tx_c, 5, 13),
GROUP(uart_rx_c, 5, 12),
GROUP(pwm_e, 5, 15),
/* Bank Z */
GROUP(eth_mdio, 4, 22),
GROUP(eth_mdc, 4, 23),
GROUP(eth_clk_rx_clk, 4, 21),
GROUP(eth_rx_dv, 4, 20),
GROUP(eth_rxd0, 4, 19),
GROUP(eth_rxd1, 4, 18),
GROUP(eth_rxd2, 4, 17),
GROUP(eth_rxd3, 4, 16),
GROUP(eth_rgmii_tx_clk, 4, 15),
GROUP(eth_tx_en, 4, 14),
GROUP(eth_txd0, 4, 13),
GROUP(eth_txd1, 4, 12),
GROUP(eth_txd2, 4, 11),
GROUP(eth_txd3, 4, 10),
/* Bank DV */
GROUP(uart_tx_b, 2, 16),
GROUP(uart_rx_b, 2, 15),
GROUP(i2c_sck_a, 1, 15),
GROUP(i2c_sda_a, 1, 14),
GROUP(i2c_sck_b, 1, 13),
GROUP(i2c_sda_b, 1, 12),
GROUP(i2c_sck_c, 1, 11),
GROUP(i2c_sda_c, 1, 10),
/* Bank BOOT */
GROUP(emmc_nand_d07, 7, 31),
GROUP(emmc_clk, 7, 30),
GROUP(emmc_cmd, 7, 29),
GROUP(emmc_ds, 7, 28),
GROUP(nand_ce0, 7, 7),
GROUP(nand_ce1, 7, 6),
GROUP(nand_rb0, 7, 5),
GROUP(nand_ale, 7, 4),
GROUP(nand_cle, 7, 3),
GROUP(nand_wen_clk, 7, 2),
GROUP(nand_ren_wr, 7, 1),
GROUP(nand_dqs, 7, 0),
/* Bank CARD */
GROUP(sdcard_d1, 6, 5),
GROUP(sdcard_d0, 6, 4),
GROUP(sdcard_d3, 6, 1),
GROUP(sdcard_d2, 6, 0),
GROUP(sdcard_cmd, 6, 2),
GROUP(sdcard_clk, 6, 3),
};
static struct meson_pmx_group meson_gxl_aobus_groups[] = {
GPIO_GROUP(GPIOAO_0, 0),
GPIO_GROUP(GPIOAO_1, 0),
GPIO_GROUP(GPIOAO_2, 0),
GPIO_GROUP(GPIOAO_3, 0),
GPIO_GROUP(GPIOAO_4, 0),
GPIO_GROUP(GPIOAO_5, 0),
GPIO_GROUP(GPIOAO_6, 0),
GPIO_GROUP(GPIOAO_7, 0),
GPIO_GROUP(GPIOAO_8, 0),
GPIO_GROUP(GPIOAO_9, 0),
/* bank AO */
GROUP(uart_tx_ao_b, 0, 26),
GROUP(uart_rx_ao_b, 0, 25),
GROUP(uart_tx_ao_a, 0, 12),
GROUP(uart_rx_ao_a, 0, 11),
GROUP(uart_cts_ao_a, 0, 10),
GROUP(uart_rts_ao_a, 0, 9),
GROUP(uart_cts_ao_b, 0, 8),
GROUP(uart_rts_ao_b, 0, 7),
GROUP(remote_input_ao, 0, 0),
};
static const char * const gpio_periphs_groups[] = {
"GPIOZ_0", "GPIOZ_1", "GPIOZ_2", "GPIOZ_3", "GPIOZ_4",
"GPIOZ_5", "GPIOZ_6", "GPIOZ_7", "GPIOZ_8", "GPIOZ_9",
"GPIOZ_10", "GPIOZ_11", "GPIOZ_12", "GPIOZ_13", "GPIOZ_14",
"GPIOZ_15",
"GPIOH_0", "GPIOH_1", "GPIOH_2", "GPIOH_3", "GPIOH_4",
"GPIOH_5", "GPIOH_6", "GPIOH_7", "GPIOH_8", "GPIOH_9",
"BOOT_0", "BOOT_1", "BOOT_2", "BOOT_3", "BOOT_4",
"BOOT_5", "BOOT_6", "BOOT_7", "BOOT_8", "BOOT_9",
"BOOT_10", "BOOT_11", "BOOT_12", "BOOT_13", "BOOT_14",
"BOOT_15",
"CARD_0", "CARD_1", "CARD_2", "CARD_3", "CARD_4",
"CARD_5", "CARD_6",
"GPIODV_0", "GPIODV_1", "GPIODV_2", "GPIODV_3", "GPIODV_4",
"GPIODV_5", "GPIODV_6", "GPIODV_7", "GPIODV_8", "GPIODV_9",
"GPIODV_10", "GPIODV_11", "GPIODV_12", "GPIODV_13", "GPIODV_14",
"GPIODV_15", "GPIODV_16", "GPIODV_17", "GPIODV_18", "GPIODV_19",
"GPIODV_20", "GPIODV_21", "GPIODV_22", "GPIODV_23", "GPIODV_24",
"GPIODV_25", "GPIODV_26", "GPIODV_27", "GPIODV_28", "GPIODV_29",
"GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", "GPIOX_4",
"GPIOX_5", "GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9",
"GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14",
"GPIOX_15", "GPIOX_16", "GPIOX_17", "GPIOX_18",
"GPIO_TEST_N",
};
static const char * const emmc_groups[] = {
"emmc_nand_d07", "emmc_clk", "emmc_cmd", "emmc_ds",
};
static const char * const sdcard_groups[] = {
"sdcard_d0", "sdcard_d1", "sdcard_d2", "sdcard_d3",
"sdcard_cmd", "sdcard_clk",
};
static const char * const sdio_groups[] = {
"sdio_d0", "sdio_d1", "sdio_d2", "sdio_d3",
"sdio_cmd", "sdio_clk", "sdio_irq",
};
static const char * const nand_groups[] = {
"nand_ce0", "nand_ce1", "nand_rb0", "nand_ale", "nand_cle",
"nand_wen_clk", "nand_ren_wr", "nand_dqs",
};
static const char * const uart_a_groups[] = {
"uart_tx_a", "uart_rx_a", "uart_cts_a", "uart_rts_a",
};
static const char * const uart_b_groups[] = {
"uart_tx_b", "uart_rx_b",
};
static const char * const uart_c_groups[] = {
"uart_tx_c", "uart_rx_c",
};
static const char * const i2c_a_groups[] = {
"i2c_sck_a", "i2c_sda_a",
};
static const char * const i2c_b_groups[] = {
"i2c_sck_b", "i2c_sda_b",
};
static const char * const i2c_c_groups[] = {
"i2c_sck_c", "i2c_sda_c",
};
static const char * const eth_groups[] = {
"eth_mdio", "eth_mdc", "eth_clk_rx_clk", "eth_rx_dv",
"eth_rxd0", "eth_rxd1", "eth_rxd2", "eth_rxd3",
"eth_rgmii_tx_clk", "eth_tx_en",
"eth_txd0", "eth_txd1", "eth_txd2", "eth_txd3",
};
static const char * const pwm_e_groups[] = {
"pwm_e",
};
static const char * const gpio_aobus_groups[] = {
"GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
"GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
};
static const char * const uart_ao_groups[] = {
"uart_tx_ao_a", "uart_rx_ao_a", "uart_cts_ao_a", "uart_rts_ao_a",
};
static const char * const uart_ao_b_groups[] = {
"uart_tx_ao_b", "uart_rx_ao_b", "uart_cts_ao_b", "uart_rts_ao_b",
};
static const char * const remote_input_ao_groups[] = {
"remote_input_ao",
};
static struct meson_pmx_func meson_gxl_periphs_functions[] = {
FUNCTION(gpio_periphs),
FUNCTION(emmc),
FUNCTION(sdcard),
FUNCTION(sdio),
FUNCTION(nand),
FUNCTION(uart_a),
FUNCTION(uart_b),
FUNCTION(uart_c),
FUNCTION(i2c_a),
FUNCTION(i2c_b),
FUNCTION(i2c_c),
FUNCTION(eth),
FUNCTION(pwm_e),
};
static struct meson_pmx_func meson_gxl_aobus_functions[] = {
FUNCTION(gpio_aobus),
FUNCTION(uart_ao),
FUNCTION(uart_ao_b),
FUNCTION(remote_input_ao),
};
static struct meson_bank meson_gxl_periphs_banks[] = {
/* name first last pullen pull dir out in */
BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_18, EE_OFF), 4, 0, 4, 0, 12, 0, 13, 0, 14, 0),
BANK("DV", PIN(GPIODV_0, EE_OFF), PIN(GPIODV_29, EE_OFF), 0, 0, 0, 0, 0, 0, 1, 0, 2, 0),
BANK("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_9, EE_OFF), 1, 20, 1, 20, 3, 20, 4, 20, 5, 20),
BANK("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_15, EE_OFF), 3, 0, 3, 0, 9, 0, 10, 0, 11, 0),
BANK("CARD", PIN(CARD_0, EE_OFF), PIN(CARD_6, EE_OFF), 2, 20, 2, 20, 6, 20, 7, 20, 8, 20),
BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_15, EE_OFF), 2, 0, 2, 0, 6, 0, 7, 0, 8, 0),
BANK("CLK", PIN(GPIOCLK_0, EE_OFF), PIN(GPIOCLK_1, EE_OFF), 3, 28, 3, 28, 9, 28, 10, 28, 11, 28),
};
static struct meson_bank meson_gxl_aobus_banks[] = {
/* name first last pullen pull dir out in */
BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_9, 0), 0, 0, 0, 16, 0, 0, 0, 16, 1, 0),
};
struct meson_pinctrl_data meson_gxl_periphs_pinctrl_data = {
.name = "periphs-banks",
.pin_base = 10,
.pins = meson_gxl_periphs_pins,
.groups = meson_gxl_periphs_groups,
.funcs = meson_gxl_periphs_functions,
.banks = meson_gxl_periphs_banks,
.num_pins = ARRAY_SIZE(meson_gxl_periphs_pins),
.num_groups = ARRAY_SIZE(meson_gxl_periphs_groups),
.num_funcs = ARRAY_SIZE(meson_gxl_periphs_functions),
.num_banks = ARRAY_SIZE(meson_gxl_periphs_banks),
};
struct meson_pinctrl_data meson_gxl_aobus_pinctrl_data = {
.name = "aobus-banks",
.pin_base = 0,
.pins = meson_gxl_aobus_pins,
.groups = meson_gxl_aobus_groups,
.funcs = meson_gxl_aobus_functions,
.banks = meson_gxl_aobus_banks,
.num_pins = ARRAY_SIZE(meson_gxl_aobus_pins),
.num_groups = ARRAY_SIZE(meson_gxl_aobus_groups),
.num_funcs = ARRAY_SIZE(meson_gxl_aobus_functions),
.num_banks = ARRAY_SIZE(meson_gxl_aobus_banks),
};
......@@ -524,6 +524,14 @@ static const struct of_device_id meson_pinctrl_dt_match[] = {
.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,
},
{ },
};
......
......@@ -169,3 +169,5 @@ 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;
......@@ -379,13 +379,24 @@ static const unsigned msp0txrx_a_1_pins[] = { DB8500_PIN_AC4, DB8500_PIN_AC3 };
static const unsigned msp0tfstck_a_1_pins[] = { DB8500_PIN_AF3, DB8500_PIN_AE3 };
static const unsigned msp0rfsrck_a_1_pins[] = { DB8500_PIN_AD3, DB8500_PIN_AD4 };
/* Basic pins of the MMC/SD card 0 interface */
static const unsigned mc0_a_1_pins[] = { DB8500_PIN_AC2, DB8500_PIN_AC1,
DB8500_PIN_AB4, DB8500_PIN_AA3, DB8500_PIN_AA4, DB8500_PIN_AB2,
DB8500_PIN_Y4, DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
static const unsigned mc0_a_1_pins[] = { DB8500_PIN_AC2, /* MC0_CMDDIR */
DB8500_PIN_AC1, /* MC0_DAT0DIR */
DB8500_PIN_AB4, /* MC0_DAT2DIR */
DB8500_PIN_AA3, /* MC0_FBCLK */
DB8500_PIN_AA4, /* MC0_CLK */
DB8500_PIN_AB2, /* MC0_CMD */
DB8500_PIN_Y4, /* MC0_DAT0 */
DB8500_PIN_Y2, /* MC0_DAT1 */
DB8500_PIN_AA2, /* MC0_DAT2 */
DB8500_PIN_AA1 /* MC0_DAT3 */
};
/* Often only 4 bits are used, then these are not needed (only used for MMC) */
static const unsigned mc0_dat47_a_1_pins[] = { DB8500_PIN_W2, DB8500_PIN_W3,
DB8500_PIN_V3, DB8500_PIN_V2};
static const unsigned mc0dat31dir_a_1_pins[] = { DB8500_PIN_AB3 };
static const unsigned mc0_dat47_a_1_pins[] = { DB8500_PIN_W2, /* MC0_DAT4 */
DB8500_PIN_W3, /* MC0_DAT5 */
DB8500_PIN_V3, /* MC0_DAT6 */
DB8500_PIN_V2 /* MC0_DAT7 */
};
static const unsigned mc0dat31dir_a_1_pins[] = { DB8500_PIN_AB3 }; /* MC0_DAT31DIR */
/* MSP1 can only be on these pins, but TXD and RXD can be flipped */
static const unsigned msp1txrx_a_1_pins[] = { DB8500_PIN_AF2, DB8500_PIN_AG2 };
static const unsigned msp1_a_1_pins[] = { DB8500_PIN_AE1, DB8500_PIN_AE2 };
......
......@@ -381,7 +381,7 @@ int pinconf_generic_dt_node_to_map(struct pinctrl_dev *pctldev,
if (ret < 0)
goto exit;
for_each_child_of_node(np_config, np) {
for_each_available_child_of_node(np_config, np) {
ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map,
&reserved_maps, num_maps, type);
if (ret < 0)
......
......@@ -56,6 +56,9 @@ static int gpio_banks;
#define DRIVE_STRENGTH_SHIFT 5
#define DRIVE_STRENGTH_MASK 0x3
#define DRIVE_STRENGTH (DRIVE_STRENGTH_MASK << DRIVE_STRENGTH_SHIFT)
#define OUTPUT (1 << 7)
#define OUTPUT_VAL_SHIFT 8
#define OUTPUT_VAL (0x1 << OUTPUT_VAL_SHIFT)
#define DEBOUNCE (1 << 16)
#define DEBOUNCE_VAL_SHIFT 17
#define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT)
......@@ -375,6 +378,19 @@ static void at91_mux_set_pullup(void __iomem *pio, unsigned mask, bool on)
writel_relaxed(mask, pio + (on ? PIO_PUER : PIO_PUDR));
}
static bool at91_mux_get_output(void __iomem *pio, unsigned int pin, bool *val)
{
*val = (readl_relaxed(pio + PIO_ODSR) >> pin) & 0x1;
return (readl_relaxed(pio + PIO_OSR) >> pin) & 0x1;
}
static void at91_mux_set_output(void __iomem *pio, unsigned int mask,
bool is_on, bool val)
{
writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR));
writel_relaxed(mask, pio + (is_on ? PIO_OER : PIO_ODR));
}
static unsigned at91_mux_get_multidrive(void __iomem *pio, unsigned pin)
{
return (readl_relaxed(pio + PIO_MDSR) >> pin) & 0x1;
......@@ -848,6 +864,7 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev,
void __iomem *pio;
unsigned pin;
int div;
bool out;
*config = 0;
dev_dbg(info->dev, "%s:%d, pin_id=%d", __func__, __LINE__, pin_id);
......@@ -875,6 +892,8 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev,
if (info->ops->get_drivestrength)
*config |= (info->ops->get_drivestrength(pio, pin)
<< DRIVE_STRENGTH_SHIFT);
if (at91_mux_get_output(pio, pin, &out))
*config |= OUTPUT | (out << OUTPUT_VAL_SHIFT);
return 0;
}
......@@ -907,6 +926,8 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev,
if (config & PULL_UP && config & PULL_DOWN)
return -EINVAL;
at91_mux_set_output(pio, mask, config & OUTPUT,
(config & OUTPUT_VAL) >> OUTPUT_VAL_SHIFT);
at91_mux_set_pullup(pio, mask, config & PULL_UP);
at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE);
if (info->ops->set_deglitch)
......
/*
* Pinconf driver for TI DA850/OMAP-L138/AM18XX pullup/pulldown groups
*
* Copyright (C) 2016 David Lechner
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
#define DA850_PUPD_ENA 0x00
#define DA850_PUPD_SEL 0x04
struct da850_pupd_data {
void __iomem *base;
struct pinctrl_desc desc;
struct pinctrl_dev *pinctrl;
};
static const char * const da850_pupd_group_names[] = {
"cp0", "cp1", "cp2", "cp3", "cp4", "cp5", "cp6", "cp7",
"cp8", "cp9", "cp10", "cp11", "cp12", "cp13", "cp14", "cp15",
"cp16", "cp17", "cp18", "cp19", "cp20", "cp21", "cp22", "cp23",
"cp24", "cp25", "cp26", "cp27", "cp28", "cp29", "cp30", "cp31",
};
static int da850_pupd_get_groups_count(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(da850_pupd_group_names);
}
static const char *da850_pupd_get_group_name(struct pinctrl_dev *pctldev,
unsigned int selector)
{
return da850_pupd_group_names[selector];
}
static int da850_pupd_get_group_pins(struct pinctrl_dev *pctldev,
unsigned int selector,
const unsigned int **pins,
unsigned int *num_pins)
{
*num_pins = 0;
return 0;
}
static const struct pinctrl_ops da850_pupd_pctlops = {
.get_groups_count = da850_pupd_get_groups_count,
.get_group_name = da850_pupd_get_group_name,
.get_group_pins = da850_pupd_get_group_pins,
.dt_node_to_map = pinconf_generic_dt_node_to_map_group,
.dt_free_map = pinconf_generic_dt_free_map,
};
static int da850_pupd_pin_config_group_get(struct pinctrl_dev *pctldev,
unsigned int selector,
unsigned long *config)
{
struct da850_pupd_data *data = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(*config);
u32 val;
u16 arg;
val = readl(data->base + DA850_PUPD_ENA);
arg = !!(~val & BIT(selector));
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
break;
case PIN_CONFIG_BIAS_PULL_UP:
case PIN_CONFIG_BIAS_PULL_DOWN:
if (arg) {
/* bias is disabled */
arg = 0;
break;
}
val = readl(data->base + DA850_PUPD_SEL);
if (param == PIN_CONFIG_BIAS_PULL_DOWN)
val = ~val;
arg = !!(val & BIT(selector));
break;
default:
return -EINVAL;
}
*config = pinconf_to_config_packed(param, arg);
return 0;
}
static int da850_pupd_pin_config_group_set(struct pinctrl_dev *pctldev,
unsigned int selector,
unsigned long *configs,
unsigned int num_configs)
{
struct da850_pupd_data *data = pinctrl_dev_get_drvdata(pctldev);
u32 ena, sel;
enum pin_config_param param;
u16 arg;
int i;
ena = readl(data->base + DA850_PUPD_ENA);
sel = readl(data->base + DA850_PUPD_SEL);
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
ena &= ~BIT(selector);
break;
case PIN_CONFIG_BIAS_PULL_UP:
ena |= BIT(selector);
sel |= BIT(selector);
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
ena |= BIT(selector);
sel &= ~BIT(selector);
break;
default:
return -EINVAL;
}
}
writel(sel, data->base + DA850_PUPD_SEL);
writel(ena, data->base + DA850_PUPD_ENA);
return 0;
}
static const struct pinconf_ops da850_pupd_confops = {
.is_generic = true,
.pin_config_group_get = da850_pupd_pin_config_group_get,
.pin_config_group_set = da850_pupd_pin_config_group_set,
};
static int da850_pupd_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct da850_pupd_data *data;
struct resource *res;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
data->base = devm_ioremap_resource(dev, res);
if (IS_ERR(data->base)) {
dev_err(dev, "Could not map resource\n");
return PTR_ERR(data->base);
}
data->desc.name = dev_name(dev);
data->desc.pctlops = &da850_pupd_pctlops;
data->desc.confops = &da850_pupd_confops;
data->desc.owner = THIS_MODULE;
data->pinctrl = devm_pinctrl_register(dev, &data->desc, data);
if (IS_ERR(data->pinctrl)) {
dev_err(dev, "Failed to register pinctrl\n");
return PTR_ERR(data->pinctrl);
}
platform_set_drvdata(pdev, data);
return 0;
}
static int da850_pupd_remove(struct platform_device *pdev)
{
return 0;
}
static const struct of_device_id da850_pupd_of_match[] = {
{ .compatible = "ti,da850-pupd" },
{ }
};
static struct platform_driver da850_pupd_driver = {
.driver = {
.name = "ti-da850-pupd",
.of_match_table = da850_pupd_of_match,
},
.probe = da850_pupd_probe,
.remove = da850_pupd_remove,
};
module_platform_driver(da850_pupd_driver);
MODULE_AUTHOR("David Lechner <david@lechnology.com>");
MODULE_DESCRIPTION("TI DA850/OMAP-L138/AM18XX pullup/pulldown configuration");
MODULE_LICENSE("GPL");
此差异已折叠。
......@@ -59,6 +59,7 @@
#define GPIO_LS_SYNC 0x60
enum rockchip_pinctrl_type {
RK1108,
RK2928,
RK3066B,
RK3188,
......@@ -624,6 +625,65 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
return ret;
}
#define RK1108_PULL_PMU_OFFSET 0x10
#define RK1108_PULL_OFFSET 0x110
#define RK1108_PULL_PINS_PER_REG 8
#define RK1108_PULL_BITS_PER_PIN 2
#define RK1108_PULL_BANK_STRIDE 16
static void rk1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
int pin_num, struct regmap **regmap,
int *reg, u8 *bit)
{
struct rockchip_pinctrl *info = bank->drvdata;
/* The first 24 pins of the first bank are located in PMU */
if (bank->bank_num == 0) {
*regmap = info->regmap_pmu;
*reg = RK1108_PULL_PMU_OFFSET;
} else {
*reg = RK1108_PULL_OFFSET;
*regmap = info->regmap_base;
/* correct the offset, as we're starting with the 2nd bank */
*reg -= 0x10;
*reg += bank->bank_num * RK1108_PULL_BANK_STRIDE;
}
*reg += ((pin_num / RK1108_PULL_PINS_PER_REG) * 4);
*bit = (pin_num % RK1108_PULL_PINS_PER_REG);
*bit *= RK1108_PULL_BITS_PER_PIN;
}
#define RK1108_DRV_PMU_OFFSET 0x20
#define RK1108_DRV_GRF_OFFSET 0x210
#define RK1108_DRV_BITS_PER_PIN 2
#define RK1108_DRV_PINS_PER_REG 8
#define RK1108_DRV_BANK_STRIDE 16
static void rk1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
int pin_num, struct regmap **regmap,
int *reg, u8 *bit)
{
struct rockchip_pinctrl *info = bank->drvdata;
/* The first 24 pins of the first bank are located in PMU */
if (bank->bank_num == 0) {
*regmap = info->regmap_pmu;
*reg = RK1108_DRV_PMU_OFFSET;
} else {
*regmap = info->regmap_base;
*reg = RK1108_DRV_GRF_OFFSET;
/* correct the offset, as we're starting with the 2nd bank */
*reg -= 0x10;
*reg += bank->bank_num * RK1108_DRV_BANK_STRIDE;
}
*reg += ((pin_num / RK1108_DRV_PINS_PER_REG) * 4);
*bit = pin_num % RK1108_DRV_PINS_PER_REG;
*bit *= RK1108_DRV_BITS_PER_PIN;
}
#define RK2928_PULL_OFFSET 0x118
#define RK2928_PULL_PINS_PER_REG 16
#define RK2928_PULL_BANK_STRIDE 8
......@@ -1123,6 +1183,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
return !(data & BIT(bit))
? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
: PIN_CONFIG_BIAS_DISABLE;
case RK1108:
case RK3188:
case RK3288:
case RK3368:
......@@ -1169,6 +1230,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
spin_unlock_irqrestore(&bank->slock, flags);
break;
case RK1108:
case RK3188:
case RK3288:
case RK3368:
......@@ -1358,6 +1420,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
pull == PIN_CONFIG_BIAS_DISABLE);
case RK3066B:
return pull ? false : true;
case RK1108:
case RK3188:
case RK3288:
case RK3368:
......@@ -2455,6 +2518,27 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
return 0;
}
static struct rockchip_pin_bank rk1108_pin_banks[] = {
PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
IOMUX_SOURCE_PMU,
IOMUX_SOURCE_PMU,
IOMUX_SOURCE_PMU),
PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0),
PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0),
PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0),
};
static struct rockchip_pin_ctrl rk1108_pin_ctrl = {
.pin_banks = rk1108_pin_banks,
.nr_banks = ARRAY_SIZE(rk1108_pin_banks),
.label = "RK1108-GPIO",
.type = RK1108,
.grf_mux_offset = 0x10,
.pmu_mux_offset = 0x0,
.pull_calc_reg = rk1108_calc_pull_reg_and_bit,
.drv_calc_reg = rk1108_calc_drv_reg_and_bit,
};
static struct rockchip_pin_bank rk2928_pin_banks[] = {
PIN_BANK(0, 32, "gpio0"),
PIN_BANK(1, 32, "gpio1"),
......@@ -2684,6 +2768,8 @@ static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
};
static const struct of_device_id rockchip_pinctrl_dt_match[] = {
{ .compatible = "rockchip,rk1108-pinctrl",
.data = (void *)&rk1108_pin_ctrl },
{ .compatible = "rockchip,rk2928-pinctrl",
.data = (void *)&rk2928_pin_ctrl },
{ .compatible = "rockchip,rk3036-pinctrl",
......
......@@ -31,12 +31,10 @@
#include <linux/platform_data/pinctrl-single.h>
#include "core.h"
#include "devicetree.h"
#include "pinconf.h"
#define DRIVER_NAME "pinctrl-single"
#define PCS_MUX_PINS_NAME "pinctrl-single,pins"
#define PCS_MUX_BITS_NAME "pinctrl-single,bits"
#define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 3)
#define PCS_OFF_DISABLED ~0U
/**
......@@ -141,20 +139,6 @@ struct pcs_data {
int cur;
};
/**
* struct pcs_name - register name for a pin
* @name: name of the pinctrl register
*
* REVISIT: We may want to make names optional in the pinctrl
* framework as some drivers may not care about pin names to
* avoid kernel bloat. The pin names can be deciphered by user
* space tools using debugfs based on the register address and
* SoC packaging information.
*/
struct pcs_name {
char name[PCS_REG_NAME_LEN];
};
/**
* struct pcs_soc_data - SoC specific settings
* @flags: initial SoC specific PCS_FEAT_xxx values
......@@ -177,8 +161,11 @@ struct pcs_soc_data {
* @base: virtual address of the controller
* @size: size of the ioremapped area
* @dev: device entry
* @np: device tree node
* @pctl: pin controller device
* @flags: mask of PCS_FEAT_xxx values
* @missing_nr_pinctrl_cells: for legacy binding, may go away
* @socdata: soc specific data
* @lock: spinlock for register access
* @mutex: mutex protecting the lists
* @width: bits per mux register
......@@ -186,8 +173,8 @@ struct pcs_soc_data {
* @fshift: function register shift
* @foff: value to turn mux off
* @fmax: max number of functions in fmask
* @bits_per_pin:number of bits per pin
* @names: array of register names for pins
* @bits_per_mux: number of bits per mux
* @bits_per_pin: number of bits per pin
* @pins: physical pins on the SoC
* @pgtree: pingroup index radix tree
* @ftree: function index radix tree
......@@ -208,11 +195,13 @@ struct pcs_device {
void __iomem *base;
unsigned size;
struct device *dev;
struct device_node *np;
struct pinctrl_dev *pctl;
unsigned flags;
#define PCS_QUIRK_SHARED_IRQ (1 << 2)
#define PCS_FEAT_IRQ (1 << 1)
#define PCS_FEAT_PINCONF (1 << 0)
struct property *missing_nr_pinctrl_cells;
struct pcs_soc_data socdata;
raw_spinlock_t lock;
struct mutex mutex;
......@@ -223,7 +212,6 @@ struct pcs_device {
unsigned fmax;
bool bits_per_mux;
unsigned bits_per_pin;
struct pcs_name *names;
struct pcs_data pins;
struct radix_tree_root pgtree;
struct radix_tree_root ftree;
......@@ -354,13 +342,17 @@ static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev,
{
struct pcs_device *pcs;
unsigned val, mux_bytes;
unsigned long offset;
size_t pa;
pcs = pinctrl_dev_get_drvdata(pctldev);
mux_bytes = pcs->width / BITS_PER_BYTE;
val = pcs->read(pcs->base + pin * mux_bytes);
offset = pin * mux_bytes;
val = pcs->read(pcs->base + offset);
pa = pcs->res->start + offset;
seq_printf(s, "%08x %s " , val, DRIVER_NAME);
seq_printf(s, "%zx %08x %s ", pa, val, DRIVER_NAME);
}
static void pcs_dt_free_map(struct pinctrl_dev *pctldev,
......@@ -763,7 +755,6 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,
{
struct pcs_soc_data *pcs_soc = &pcs->socdata;
struct pinctrl_pin_desc *pin;
struct pcs_name *pn;
int i;
i = pcs->pins.cur;
......@@ -786,10 +777,6 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,
}
pin = &pcs->pins.pa[i];
pn = &pcs->names[i];
sprintf(pn->name, "%lx.%u",
(unsigned long)pcs->res->start + offset, pin_pos);
pin->name = pn->name;
pin->number = i;
pcs->pins.cur++;
......@@ -827,12 +814,6 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs)
if (!pcs->pins.pa)
return -ENOMEM;
pcs->names = devm_kzalloc(pcs->dev,
sizeof(struct pcs_name) * nr_pins,
GFP_KERNEL);
if (!pcs->names)
return -ENOMEM;
pcs->desc.pins = pcs->pins.pa;
pcs->desc.npins = nr_pins;
......@@ -1146,21 +1127,17 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
unsigned *num_maps,
const char **pgnames)
{
const char *name = "pinctrl-single,pins";
struct pcs_func_vals *vals;
const __be32 *mux;
int size, rows, *pins, index = 0, found = 0, res = -ENOMEM;
int rows, *pins, found = 0, res = -ENOMEM, i;
struct pcs_function *function;
mux = of_get_property(np, PCS_MUX_PINS_NAME, &size);
if ((!mux) || (size < sizeof(*mux) * 2)) {
dev_err(pcs->dev, "bad data for mux %s\n",
np->name);
rows = pinctrl_count_index_with_args(np, name);
if (rows <= 0) {
dev_err(pcs->dev, "Ivalid number of rows: %d\n", rows);
return -EINVAL;
}
size /= sizeof(*mux); /* Number of elements in array */
rows = size / 2;
vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows, GFP_KERNEL);
if (!vals)
return -ENOMEM;
......@@ -1169,14 +1146,28 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
if (!pins)
goto free_vals;
while (index < size) {
unsigned offset, val;
for (i = 0; i < rows; i++) {
struct of_phandle_args pinctrl_spec;
unsigned int offset;
int pin;
offset = be32_to_cpup(mux + index++);
val = be32_to_cpup(mux + index++);
res = pinctrl_parse_index_with_args(np, name, i, &pinctrl_spec);
if (res)
return res;
if (pinctrl_spec.args_count < 2) {
dev_err(pcs->dev, "invalid args_count for spec: %i\n",
pinctrl_spec.args_count);
break;
}
/* Index plus one value cell */
offset = pinctrl_spec.args[0];
vals[found].reg = pcs->base + offset;
vals[found].val = val;
vals[found].val = pinctrl_spec.args[1];
dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x\n",
pinctrl_spec.np->name, offset, pinctrl_spec.args[1]);
pin = pcs_get_pin_by_offset(pcs, offset);
if (pin < 0) {
......@@ -1190,8 +1181,10 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
pgnames[0] = np->name;
function = pcs_add_function(pcs, np, np->name, vals, found, pgnames, 1);
if (!function)
if (!function) {
res = -ENOMEM;
goto free_pins;
}
res = pcs_add_pingroup(pcs, np, np->name, pins, found);
if (res < 0)
......@@ -1226,36 +1219,24 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
return res;
}
#define PARAMS_FOR_BITS_PER_MUX 3
static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
struct device_node *np,
struct pinctrl_map **map,
unsigned *num_maps,
const char **pgnames)
{
const char *name = "pinctrl-single,bits";
struct pcs_func_vals *vals;
const __be32 *mux;
int size, rows, *pins, index = 0, found = 0, res = -ENOMEM;
int rows, *pins, found = 0, res = -ENOMEM, i;
int npins_in_row;
struct pcs_function *function;
mux = of_get_property(np, PCS_MUX_BITS_NAME, &size);
if (!mux) {
dev_err(pcs->dev, "no valid property for %s\n", np->name);
return -EINVAL;
}
if (size < (sizeof(*mux) * PARAMS_FOR_BITS_PER_MUX)) {
dev_err(pcs->dev, "bad data for %s\n", np->name);
rows = pinctrl_count_index_with_args(np, name);
if (rows <= 0) {
dev_err(pcs->dev, "Invalid number of rows: %d\n", rows);
return -EINVAL;
}
/* Number of elements in array */
size /= sizeof(*mux);
rows = size / PARAMS_FOR_BITS_PER_MUX;
npins_in_row = pcs->width / pcs->bits_per_pin;
vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows * npins_in_row,
......@@ -1268,15 +1249,30 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
if (!pins)
goto free_vals;
while (index < size) {
for (i = 0; i < rows; i++) {
struct of_phandle_args pinctrl_spec;
unsigned offset, val;
unsigned mask, bit_pos, val_pos, mask_pos, submask;
unsigned pin_num_from_lsb;
int pin;
offset = be32_to_cpup(mux + index++);
val = be32_to_cpup(mux + index++);
mask = be32_to_cpup(mux + index++);
res = pinctrl_parse_index_with_args(np, name, i, &pinctrl_spec);
if (res)
return res;
if (pinctrl_spec.args_count < 3) {
dev_err(pcs->dev, "invalid args_count for spec: %i\n",
pinctrl_spec.args_count);
break;
}
/* Index plus two value cells */
offset = pinctrl_spec.args[0];
val = pinctrl_spec.args[1];
mask = pinctrl_spec.args[2];
dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x mask: 0x%x\n",
pinctrl_spec.np->name, offset, val, mask);
/* Parse pins in each row from LSB */
while (mask) {
......@@ -1319,8 +1315,10 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
pgnames[0] = np->name;
function = pcs_add_function(pcs, np, np->name, vals, found, pgnames, 1);
if (!function)
if (!function) {
res = -ENOMEM;
goto free_pins;
}
res = pcs_add_pingroup(pcs, np, np->name, pins, found);
if (res < 0)
......@@ -1494,17 +1492,12 @@ static void pcs_free_resources(struct pcs_device *pcs)
pinctrl_unregister(pcs->pctl);
pcs_free_funcs(pcs);
pcs_free_pingroups(pcs);
#if IS_BUILTIN(CONFIG_PINCTRL_SINGLE)
if (pcs->missing_nr_pinctrl_cells)
of_remove_property(pcs->np, pcs->missing_nr_pinctrl_cells);
#endif
}
#define PCS_GET_PROP_U32(name, reg, err) \
do { \
ret = of_property_read_u32(np, name, reg); \
if (ret) { \
dev_err(pcs->dev, err); \
return ret; \
} \
} while (0);
static const struct of_device_id pcs_of_match[];
static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs)
......@@ -1820,6 +1813,55 @@ static int pinctrl_single_resume(struct platform_device *pdev)
}
#endif
/**
* pcs_quirk_missing_pinctrl_cells - handle legacy binding
* @pcs: pinctrl driver instance
* @np: device tree node
* @cells: number of cells
*
* Handle legacy binding with no #pinctrl-cells. This should be
* always two pinctrl-single,bit-per-mux and one for others.
* At some point we may want to consider removing this.
*/
static int pcs_quirk_missing_pinctrl_cells(struct pcs_device *pcs,
struct device_node *np,
int cells)
{
struct property *p;
const char *name = "#pinctrl-cells";
int error;
u32 val;
error = of_property_read_u32(np, name, &val);
if (!error)
return 0;
dev_warn(pcs->dev, "please update dts to use %s = <%i>\n",
name, cells);
p = devm_kzalloc(pcs->dev, sizeof(*p), GFP_KERNEL);
if (!p)
return -ENOMEM;
p->length = sizeof(__be32);
p->value = devm_kzalloc(pcs->dev, sizeof(__be32), GFP_KERNEL);
if (!p->value)
return -ENOMEM;
*(__be32 *)p->value = cpu_to_be32(cells);
p->name = devm_kstrdup(pcs->dev, name, GFP_KERNEL);
if (!p->name)
return -ENOMEM;
pcs->missing_nr_pinctrl_cells = p;
#if IS_BUILTIN(CONFIG_PINCTRL_SINGLE)
error = of_add_property(np, pcs->missing_nr_pinctrl_cells);
#endif
return error;
}
static int pcs_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
......@@ -1840,6 +1882,7 @@ static int pcs_probe(struct platform_device *pdev)
return -ENOMEM;
}
pcs->dev = &pdev->dev;
pcs->np = np;
raw_spin_lock_init(&pcs->lock);
mutex_init(&pcs->mutex);
INIT_LIST_HEAD(&pcs->pingroups);
......@@ -1849,8 +1892,13 @@ static int pcs_probe(struct platform_device *pdev)
pcs->flags = soc->flags;
memcpy(&pcs->socdata, soc, sizeof(*soc));
PCS_GET_PROP_U32("pinctrl-single,register-width", &pcs->width,
"register width not specified\n");
ret = of_property_read_u32(np, "pinctrl-single,register-width",
&pcs->width);
if (ret) {
dev_err(pcs->dev, "register width not specified\n");
return ret;
}
ret = of_property_read_u32(np, "pinctrl-single,function-mask",
&pcs->fmask);
......@@ -1871,6 +1919,13 @@ static int pcs_probe(struct platform_device *pdev)
pcs->bits_per_mux = of_property_read_bool(np,
"pinctrl-single,bit-per-mux");
ret = pcs_quirk_missing_pinctrl_cells(pcs, np,
pcs->bits_per_mux ? 2 : 1);
if (ret) {
dev_err(&pdev->dev, "unable to patch #pinctrl-cells\n");
return ret;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
......
......@@ -1006,7 +1006,7 @@ static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev,
function = st_pctl_get_pin_function(pc, offset);
if (function)
snprintf(f, 10, "Alt Fn %d", function);
snprintf(f, 10, "Alt Fn %u", function);
else
snprintf(f, 5, "GPIO");
......@@ -1181,7 +1181,7 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
if (!strcmp(pp->name, "name"))
continue;
if (pp && (pp->length/sizeof(__be32)) >= OF_GPIO_ARGS_MIN) {
if (pp->length / sizeof(__be32) >= OF_GPIO_ARGS_MIN) {
npins++;
} else {
pr_warn("Invalid st,pins in %s node\n", np->name);
......
此差异已折叠。
......@@ -247,6 +247,8 @@ static const unsigned int smc0_nor_addr25_pins[] = {1};
static const unsigned int smc0_nand_pins[] = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 16, 17, 18, 19, 20,
21, 22, 23};
static const unsigned int smc0_nand8_pins[] = {0, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14};
/* Note: CAN MIO clock inputs are modeled in the clock framework */
static const unsigned int can0_0_pins[] = {10, 11};
static const unsigned int can0_1_pins[] = {14, 15};
......@@ -445,6 +447,7 @@ static const struct zynq_pctrl_group zynq_pctrl_groups[] = {
DEFINE_ZYNQ_PINCTRL_GRP(smc0_nor_cs1),
DEFINE_ZYNQ_PINCTRL_GRP(smc0_nor_addr25),
DEFINE_ZYNQ_PINCTRL_GRP(smc0_nand),
DEFINE_ZYNQ_PINCTRL_GRP(smc0_nand8),
DEFINE_ZYNQ_PINCTRL_GRP(can0_0),
DEFINE_ZYNQ_PINCTRL_GRP(can0_1),
DEFINE_ZYNQ_PINCTRL_GRP(can0_2),
......@@ -709,7 +712,8 @@ static const char * const sdio1_wp_groups[] = {"gpio0_0_grp",
static const char * const smc0_nor_groups[] = {"smc0_nor_grp"};
static const char * const smc0_nor_cs1_groups[] = {"smc0_nor_cs1_grp"};
static const char * const smc0_nor_addr25_groups[] = {"smc0_nor_addr25_grp"};
static const char * const smc0_nand_groups[] = {"smc0_nand_grp"};
static const char * const smc0_nand_groups[] = {"smc0_nand_grp",
"smc0_nand8_grp"};
static const char * const can0_groups[] = {"can0_0_grp", "can0_1_grp",
"can0_2_grp", "can0_3_grp", "can0_4_grp", "can0_5_grp",
"can0_6_grp", "can0_7_grp", "can0_8_grp", "can0_9_grp",
......
......@@ -79,6 +79,15 @@ config PINCTRL_MSM8916
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found on the Qualcomm 8916 platform.
config PINCTRL_MSM8994
tristate "Qualcomm 8994 pin controller driver"
depends on GPIOLIB && OF
select PINCTRL_MSM
help
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found in the Qualcomm 8994 platform. The
Qualcomm 8992 platform is also supported by this driver.
config PINCTRL_MSM8996
tristate "Qualcomm MSM8996 pin controller driver"
depends on GPIOLIB && OF
......
......@@ -8,6 +8,7 @@ obj-$(CONFIG_PINCTRL_MSM8660) += pinctrl-msm8660.o
obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o
obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
obj-$(CONFIG_PINCTRL_MSM8916) += pinctrl-msm8916.o
obj-$(CONFIG_PINCTRL_MSM8994) += pinctrl-msm8994.o
obj-$(CONFIG_PINCTRL_MSM8996) += pinctrl-msm8996.o
obj-$(CONFIG_PINCTRL_QDF2XXX) += pinctrl-qdf2xxx.o
obj-$(CONFIG_PINCTRL_MDM9615) += pinctrl-mdm9615.o
......
此差异已折叠。
......@@ -61,16 +61,15 @@ static void exynos_irq_mask(struct irq_data *irqd)
struct irq_chip *chip = irq_data_get_irq_chip(irqd);
struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
unsigned long mask;
unsigned long flags;
spin_lock_irqsave(&bank->slock, flags);
mask = readl(d->virt_base + reg_mask);
mask = readl(bank->eint_base + reg_mask);
mask |= 1 << irqd->hwirq;
writel(mask, d->virt_base + reg_mask);
writel(mask, bank->eint_base + reg_mask);
spin_unlock_irqrestore(&bank->slock, flags);
}
......@@ -80,10 +79,9 @@ static void exynos_irq_ack(struct irq_data *irqd)
struct irq_chip *chip = irq_data_get_irq_chip(irqd);
struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned long reg_pend = our_chip->eint_pend + bank->eint_offset;
writel(1 << irqd->hwirq, d->virt_base + reg_pend);
writel(1 << irqd->hwirq, bank->eint_base + reg_pend);
}
static void exynos_irq_unmask(struct irq_data *irqd)
......@@ -91,7 +89,6 @@ static void exynos_irq_unmask(struct irq_data *irqd)
struct irq_chip *chip = irq_data_get_irq_chip(irqd);
struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
unsigned long mask;
unsigned long flags;
......@@ -109,9 +106,9 @@ static void exynos_irq_unmask(struct irq_data *irqd)
spin_lock_irqsave(&bank->slock, flags);
mask = readl(d->virt_base + reg_mask);
mask = readl(bank->eint_base + reg_mask);
mask &= ~(1 << irqd->hwirq);
writel(mask, d->virt_base + reg_mask);
writel(mask, bank->eint_base + reg_mask);
spin_unlock_irqrestore(&bank->slock, flags);
}
......@@ -121,7 +118,6 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
struct irq_chip *chip = irq_data_get_irq_chip(irqd);
struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq;
unsigned int con, trig_type;
unsigned long reg_con = our_chip->eint_con + bank->eint_offset;
......@@ -152,10 +148,10 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
else
irq_set_handler_locked(irqd, handle_level_irq);
con = readl(d->virt_base + reg_con);
con = readl(bank->eint_base + reg_con);
con &= ~(EXYNOS_EINT_CON_MASK << shift);
con |= trig_type << shift;
writel(con, d->virt_base + reg_con);
writel(con, bank->eint_base + reg_con);
return 0;
}
......@@ -166,7 +162,6 @@ static int exynos_irq_request_resources(struct irq_data *irqd)
struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
const struct samsung_pin_bank_type *bank_type = bank->type;
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq;
unsigned long reg_con = our_chip->eint_con + bank->eint_offset;
unsigned long flags;
......@@ -188,10 +183,10 @@ static int exynos_irq_request_resources(struct irq_data *irqd)
spin_lock_irqsave(&bank->slock, flags);
con = readl(d->virt_base + reg_con);
con = readl(bank->eint_base + reg_con);
con &= ~(mask << shift);
con |= EXYNOS_EINT_FUNC << shift;
writel(con, d->virt_base + reg_con);
writel(con, bank->eint_base + reg_con);
spin_unlock_irqrestore(&bank->slock, flags);
......@@ -206,7 +201,6 @@ static void exynos_irq_release_resources(struct irq_data *irqd)
struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
const struct samsung_pin_bank_type *bank_type = bank->type;
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq;
unsigned long reg_con = our_chip->eint_con + bank->eint_offset;
unsigned long flags;
......@@ -221,10 +215,10 @@ static void exynos_irq_release_resources(struct irq_data *irqd)
spin_lock_irqsave(&bank->slock, flags);
con = readl(d->virt_base + reg_con);
con = readl(bank->eint_base + reg_con);
con &= ~(mask << shift);
con |= FUNC_INPUT << shift;
writel(con, d->virt_base + reg_con);
writel(con, bank->eint_base + reg_con);
spin_unlock_irqrestore(&bank->slock, flags);
......@@ -274,7 +268,7 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
struct samsung_pin_bank *bank = d->pin_banks;
unsigned int svc, group, pin, virq;
svc = readl(d->virt_base + EXYNOS_SVC_OFFSET);
svc = readl(bank->eint_base + EXYNOS_SVC_OFFSET);
group = EXYNOS_SVC_GROUP(svc);
pin = svc & EXYNOS_SVC_NUM_MASK;
......@@ -452,7 +446,6 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
{
struct irq_chip *chip = irq_desc_get_chip(desc);
struct exynos_muxed_weint_data *eintd = irq_desc_get_handler_data(desc);
struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata;
unsigned long pend;
unsigned long mask;
int i;
......@@ -461,9 +454,9 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
for (i = 0; i < eintd->nr_banks; ++i) {
struct samsung_pin_bank *b = eintd->banks[i];
pend = readl(d->virt_base + b->irq_chip->eint_pend
pend = readl(b->eint_base + b->irq_chip->eint_pend
+ b->eint_offset);
mask = readl(d->virt_base + b->irq_chip->eint_mask
mask = readl(b->eint_base + b->irq_chip->eint_mask
+ b->eint_offset);
exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
}
......@@ -581,7 +574,7 @@ static void exynos_pinctrl_suspend_bank(
struct samsung_pin_bank *bank)
{
struct exynos_eint_gpio_save *save = bank->soc_priv;
void __iomem *regs = drvdata->virt_base;
void __iomem *regs = bank->eint_base;
save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
+ bank->eint_offset);
......@@ -610,7 +603,7 @@ static void exynos_pinctrl_resume_bank(
struct samsung_pin_bank *bank)
{
struct exynos_eint_gpio_save *save = bank->soc_priv;
void __iomem *regs = drvdata->virt_base;
void __iomem *regs = bank->eint_base;
pr_debug("%s: con %#010x => %#010x\n", bank->name,
readl(regs + EXYNOS_GPIO_ECON_OFFSET
......@@ -1346,6 +1339,11 @@ static const struct samsung_pin_bank_data exynos5433_pin_banks0[] = {
EXYNOS_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04),
EXYNOS_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08),
EXYNOS_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c),
EXYNOS_PIN_BANK_EINTW_EXT(8, 0x020, "gpf1", 0x1004, 1),
EXYNOS_PIN_BANK_EINTW_EXT(4, 0x040, "gpf2", 0x1008, 1),
EXYNOS_PIN_BANK_EINTW_EXT(4, 0x060, "gpf3", 0x100c, 1),
EXYNOS_PIN_BANK_EINTW_EXT(8, 0x080, "gpf4", 0x1010, 1),
EXYNOS_PIN_BANK_EINTW_EXT(8, 0x0a0, "gpf5", 0x1014, 1),
};
/* pin banks of exynos5433 pin-controller - AUD */
......@@ -1427,6 +1425,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] = {
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.nr_ext_resources = 1,
}, {
/* pin-controller instance 1 data */
.pin_banks = exynos5433_pin_banks1,
......
......@@ -79,6 +79,17 @@
.name = id \
}
#define EXYNOS_PIN_BANK_EINTW_EXT(pins, reg, id, offs, pctl_idx) \
{ \
.type = &bank_type_alive, \
.pctl_offset = reg, \
.nr_pins = pins, \
.eint_type = EINT_TYPE_WKUP, \
.eint_offset = offs, \
.name = id, \
.pctl_res_idx = pctl_idx, \
} \
/**
* struct exynos_weint_data: irq specific data for all the wakeup interrupts
* generated by the external wakeup interrupt controller.
......
......@@ -151,7 +151,7 @@ static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d,
u32 val;
/* Make sure that pin is configured as interrupt */
reg = d->virt_base + bank->pctl_offset;
reg = bank->pctl_base + bank->pctl_offset;
shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
......@@ -184,7 +184,7 @@ static int s3c24xx_eint_type(struct irq_data *data, unsigned int type)
s3c24xx_eint_set_handler(data, type);
/* Set up interrupt trigger */
reg = d->virt_base + EINT_REG(index);
reg = bank->eint_base + EINT_REG(index);
shift = EINT_OFFS(index);
val = readl(reg);
......@@ -259,32 +259,29 @@ static void s3c2410_demux_eint0_3(struct irq_desc *desc)
static void s3c2412_eint0_3_ack(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned long bitval = 1UL << data->hwirq;
writel(bitval, d->virt_base + EINTPEND_REG);
writel(bitval, bank->eint_base + EINTPEND_REG);
}
static void s3c2412_eint0_3_mask(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned long mask;
mask = readl(d->virt_base + EINTMASK_REG);
mask = readl(bank->eint_base + EINTMASK_REG);
mask |= (1UL << data->hwirq);
writel(mask, d->virt_base + EINTMASK_REG);
writel(mask, bank->eint_base + EINTMASK_REG);
}
static void s3c2412_eint0_3_unmask(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned long mask;
mask = readl(d->virt_base + EINTMASK_REG);
mask = readl(bank->eint_base + EINTMASK_REG);
mask &= ~(1UL << data->hwirq);
writel(mask, d->virt_base + EINTMASK_REG);
writel(mask, bank->eint_base + EINTMASK_REG);
}
static struct irq_chip s3c2412_eint0_3_chip = {
......@@ -319,34 +316,31 @@ static void s3c2412_demux_eint0_3(struct irq_desc *desc)
static void s3c24xx_eint_ack(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned char index = bank->eint_offset + data->hwirq;
writel(1UL << index, d->virt_base + EINTPEND_REG);
writel(1UL << index, bank->eint_base + EINTPEND_REG);
}
static void s3c24xx_eint_mask(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned char index = bank->eint_offset + data->hwirq;
unsigned long mask;
mask = readl(d->virt_base + EINTMASK_REG);
mask = readl(bank->eint_base + EINTMASK_REG);
mask |= (1UL << index);
writel(mask, d->virt_base + EINTMASK_REG);
writel(mask, bank->eint_base + EINTMASK_REG);
}
static void s3c24xx_eint_unmask(struct irq_data *data)
{
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
unsigned char index = bank->eint_offset + data->hwirq;
unsigned long mask;
mask = readl(d->virt_base + EINTMASK_REG);
mask = readl(bank->eint_base + EINTMASK_REG);
mask &= ~(1UL << index);
writel(mask, d->virt_base + EINTMASK_REG);
writel(mask, bank->eint_base + EINTMASK_REG);
}
static struct irq_chip s3c24xx_eint_chip = {
......@@ -362,13 +356,14 @@ static inline void s3c24xx_demux_eint(struct irq_desc *desc,
{
struct s3c24xx_eint_data *data = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_desc_get_chip(desc);
struct samsung_pinctrl_drv_data *d = data->drvdata;
struct irq_data *irqd = irq_desc_get_irq_data(desc);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
unsigned int pend, mask;
chained_irq_enter(chip, desc);
pend = readl(d->virt_base + EINTPEND_REG);
mask = readl(d->virt_base + EINTMASK_REG);
pend = readl(bank->eint_base + EINTPEND_REG);
mask = readl(bank->eint_base + EINTMASK_REG);
pend &= ~mask;
pend &= range;
......
......@@ -389,6 +389,21 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type)
return 0;
}
const struct sh_pfc_bias_info *
sh_pfc_pin_to_bias_info(const struct sh_pfc_bias_info *info,
unsigned int num, unsigned int pin)
{
unsigned int i;
for (i = 0; i < num; i++)
if (info[i].pin == pin)
return &info[i];
WARN_ONCE(1, "Pin %u is not in bias info list\n", pin);
return NULL;
}
static int sh_pfc_init_ranges(struct sh_pfc *pfc)
{
struct sh_pfc_pin_range *range;
......
......@@ -33,4 +33,8 @@ void sh_pfc_write_reg(struct sh_pfc *pfc, u32 reg, unsigned int width,
int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin);
int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type);
const struct sh_pfc_bias_info *
sh_pfc_pin_to_bias_info(const struct sh_pfc_bias_info *info,
unsigned int num, unsigned int pin);
#endif /* __SH_PFC_CORE_H__ */
......@@ -570,7 +570,8 @@ static bool sh_pfc_pinconf_validate(struct sh_pfc *pfc, unsigned int _pin,
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
return true;
return pin->configs &
(SH_PFC_PIN_CFG_PULL_UP | SH_PFC_PIN_CFG_PULL_DOWN);
case PIN_CONFIG_BIAS_PULL_UP:
return pin->configs & SH_PFC_PIN_CFG_PULL_UP;
......
此差异已折叠。
......@@ -1584,8 +1584,4 @@ static struct platform_driver stm32f429_pinctrl_driver = {
},
};
static int __init stm32f429_pinctrl_init(void)
{
return platform_driver_register(&stm32f429_pinctrl_driver);
}
device_initcall(stm32f429_pinctrl_init);
builtin_platform_driver(stm32f429_pinctrl_driver);
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册