Commit 8a1a3b1d authored by Simon Horman's avatar Simon Horman

Merge commit '70c8f01a' into dt3-base

This is a commit from the for-next branch of Linus Walleij's pin control tre
git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git

It is the oldest commit in that branch that provides the dependencies
needed for SoC changes to the usage of sh-pfc.
parents bd060989 70c8f01a
* Freescale IMX25 IOMUX Controller
Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
and usage.
CONFIG bits definition:
PAD_CTL_HYS (1 << 8)
PAD_CTL_PKE (1 << 7)
PAD_CTL_PUE (1 << 6)
PAD_CTL_PUS_100K_DOWN (0 << 4)
PAD_CTL_PUS_47K_UP (1 << 4)
PAD_CTL_PUS_100K_UP (2 << 4)
PAD_CTL_PUS_22K_UP (3 << 4)
PAD_CTL_ODE_CMOS (0 << 3)
PAD_CTL_ODE_OPENDRAIN (1 << 3)
PAD_CTL_DSE_NOMINAL (0 << 1)
PAD_CTL_DSE_HIGH (1 << 1)
PAD_CTL_DSE_MAX (2 << 1)
PAD_CTL_SRE_FAST (1 << 0)
PAD_CTL_SRE_SLOW (0 << 0)
Refer to imx25-pinfunc.h in device tree source folder for all available
imx25 PIN_FUNC_ID.
......@@ -52,12 +52,25 @@ Required properties for pin configuration node:
CONFIG can be 0 or 1, meaning Pullup disable/enable.
The iomux controller has gpio child nodes which are embedded in the iomux
control registers. They have to be defined as child nodes of the iomux device
node. If gpio subnodes are defined "#address-cells", "#size-cells" and "ranges"
properties for the iomux device node are required.
Example:
iomuxc: iomuxc@10015000 {
compatible = "fsl,imx27-iomuxc";
reg = <0x10015000 0x600>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
gpio1: gpio@10015000 {
...
};
...
uart {
pinctrl_uart1: uart-1 {
......@@ -83,6 +96,15 @@ The above example using macros:
iomuxc: iomuxc@10015000 {
compatible = "fsl,imx27-iomuxc";
reg = <0x10015000 0x600>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
gpio1: gpio@10015000 {
...
};
...
uart {
pinctrl_uart1: uart-1 {
......
Qualcomm MSM8x74 TLMM block
Required properties:
- compatible: "qcom,msm8x74-pinctrl"
- reg: Should be the base address and length of the TLMM block.
- interrupts: Should be the parent IRQ of the TLMM block.
- interrupt-controller: Marks the device node as an interrupt controller.
- #interrupt-cells: Should be two.
- gpio-controller: Marks the device node as a GPIO controller.
- #gpio-cells : Should be two.
The first cell is the gpio pin number and the
second cell is used for optional parameters.
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".
Qualcomm's pin configuration nodes act as a container for an abitrary 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.
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, function, bias-disable, bias-pull-down, bias-pull,up, drive-strength.
Non-empty subnodes must specify the 'pins' property.
Note that not all properties are valid for all pins.
Valid values for qcom,pins are:
gpio0-gpio145
Supports mux, bias and drive-strength
sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd, sdc2_data
Supports bias and drive-strength
Valid values for qcom,function are:
blsp_i2c2, blsp_i2c6, blsp_i2c11, blsp_spi1, blsp_uart2, blsp_uart8, slimbus
(Note that this is not yet the complete list of functions)
Example:
msmgpio: pinctrl@fd510000 {
compatible = "qcom,msm8x74-pinctrl";
reg = <0xfd510000 0x4000>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <0 208 0>;
pinctrl-names = "default";
pinctrl-0 = <&uart2_default>;
uart2_default: uart2_default {
mux {
qcom,pins = "gpio4", "gpio5";
qcom,function = "blsp_uart2";
};
tx {
qcom,pins = "gpio4";
drive-strength = <4>;
bias-disable;
};
rx {
qcom,pins = "gpio5";
drive-strength = <2>;
bias-pull-up;
};
};
};
......@@ -26,6 +26,11 @@ Optional properties:
- #gpio-range-cells: Mandatory when the PFC doesn't handle GPIO, forbidden
otherwise. Should be 3.
- interrupts-extended: Specify the interrupts associated with external
IRQ pins. This property is mandatory when the PFC handles GPIOs and
forbidden otherwise. When specified, it must contain one interrupt per
external IRQ, sorted by external IRQ number.
The PFC node also acts as a container for pin configuration nodes. Please refer
to pinctrl-bindings.txt in this directory for the definition of the term "pin
configuration node" and for the common pinctrl bindings used by client devices.
......@@ -103,6 +108,15 @@ Example 1: SH73A0 (SH-Mobile AG5) pin controller node
<0xe605801c 0x1c>;
gpio-controller;
#gpio-cells = <2>;
interrupts-extended =
<&irqpin0 0 0>, <&irqpin0 1 0>, <&irqpin0 2 0>, <&irqpin0 3 0>,
<&irqpin0 4 0>, <&irqpin0 5 0>, <&irqpin0 6 0>, <&irqpin0 7 0>,
<&irqpin1 0 0>, <&irqpin1 1 0>, <&irqpin1 2 0>, <&irqpin1 3 0>,
<&irqpin1 4 0>, <&irqpin1 5 0>, <&irqpin1 6 0>, <&irqpin1 7 0>,
<&irqpin2 0 0>, <&irqpin2 1 0>, <&irqpin2 2 0>, <&irqpin2 3 0>,
<&irqpin2 4 0>, <&irqpin2 5 0>, <&irqpin2 6 0>, <&irqpin2 7 0>,
<&irqpin3 0 0>, <&irqpin3 1 0>, <&irqpin3 2 0>, <&irqpin3 3 0>,
<&irqpin3 4 0>, <&irqpin3 5 0>, <&irqpin3 6 0>, <&irqpin3 7 0>;
};
Example 2: A GPIO LED node that references a GPIO
......
......@@ -116,15 +116,22 @@ config PINCTRL_IMX1_CORE
config PINCTRL_IMX27
bool "IMX27 pinctrl driver"
depends on OF
depends on SOC_IMX27
select PINCTRL_IMX1_CORE
help
Say Y here to enable the imx27 pinctrl driver
config PINCTRL_IMX25
bool "IMX25 pinctrl driver"
depends on OF
depends on SOC_IMX25
select PINCTRL_IMX
help
Say Y here to enable the imx25 pinctrl driver
config PINCTRL_IMX35
bool "IMX35 pinctrl driver"
depends on OF
depends on SOC_IMX35
select PINCTRL_IMX
help
......@@ -132,7 +139,6 @@ config PINCTRL_IMX35
config PINCTRL_IMX50
bool "IMX50 pinctrl driver"
depends on OF
depends on SOC_IMX50
select PINCTRL_IMX
help
......@@ -140,7 +146,6 @@ config PINCTRL_IMX50
config PINCTRL_IMX51
bool "IMX51 pinctrl driver"
depends on OF
depends on SOC_IMX51
select PINCTRL_IMX
help
......@@ -148,7 +153,6 @@ config PINCTRL_IMX51
config PINCTRL_IMX53
bool "IMX53 pinctrl driver"
depends on OF
depends on SOC_IMX53
select PINCTRL_IMX
help
......@@ -156,7 +160,6 @@ config PINCTRL_IMX53
config PINCTRL_IMX6Q
bool "IMX6Q/DL pinctrl driver"
depends on OF
depends on SOC_IMX6Q
select PINCTRL_IMX
help
......@@ -164,7 +167,6 @@ config PINCTRL_IMX6Q
config PINCTRL_IMX6SL
bool "IMX6SL pinctrl driver"
depends on OF
depends on SOC_IMX6SL
select PINCTRL_IMX
help
......@@ -172,7 +174,6 @@ config PINCTRL_IMX6SL
config PINCTRL_VF610
bool "Freescale Vybrid VF610 pinctrl driver"
depends on OF
depends on SOC_VF610
select PINCTRL_IMX
help
......@@ -202,6 +203,17 @@ config PINCTRL_IMX28
bool
select PINCTRL_MXS
config PINCTRL_MSM
bool
select PINMUX
select PINCONF
select GENERIC_PINCONF
config PINCTRL_MSM8X74
bool "Qualcomm 8x74 pin controller driver"
depends on OF && OF_IRQ
select PINCTRL_MSM
config PINCTRL_NOMADIK
bool "Nomadik pin controller driver"
depends on ARCH_U8500 || ARCH_NOMADIK
......
......@@ -34,7 +34,10 @@ obj-$(CONFIG_PINCTRL_IMX6SL) += pinctrl-imx6sl.o
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o
obj-$(CONFIG_PINCTRL_IMX25) += pinctrl-imx25.o
obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o
obj-$(CONFIG_PINCTRL_MSM) += pinctrl-msm.o
obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o
obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o
obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o
......
......@@ -28,12 +28,6 @@ int pinconf_check_ops(struct pinctrl_dev *pctldev)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
/* We must be able to read out pin status */
if (!ops->pin_config_get && !ops->pin_config_group_get) {
dev_err(pctldev->dev,
"pinconf must be able to read out pin status\n");
return -EINVAL;
}
/* We have to be able to config the pins in SOME way */
if (!ops->pin_config_set && !ops->pin_config_group_set) {
dev_err(pctldev->dev,
......@@ -67,9 +61,9 @@ int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
const struct pinconf_ops *ops = pctldev->desc->confops;
if (!ops || !ops->pin_config_get) {
dev_err(pctldev->dev, "cannot get pin configuration, missing "
dev_dbg(pctldev->dev, "cannot get pin configuration, missing "
"pin_config_get() function in driver\n");
return -EINVAL;
return -ENOTSUPP;
}
return ops->pin_config_get(pctldev, pin, config);
......@@ -93,10 +87,10 @@ int pin_config_group_get(const char *dev_name, const char *pin_group,
ops = pctldev->desc->confops;
if (!ops || !ops->pin_config_group_get) {
dev_err(pctldev->dev, "cannot get configuration for pin "
dev_dbg(pctldev->dev, "cannot get configuration for pin "
"group, missing group config get function in "
"driver\n");
ret = -EINVAL;
ret = -ENOTSUPP;
goto unlock;
}
......@@ -305,9 +299,6 @@ static int pinconf_pins_show(struct seq_file *s, void *what)
const struct pinconf_ops *ops = pctldev->desc->confops;
unsigned i, pin;
if (!ops || !ops->pin_config_get)
return 0;
seq_puts(s, "Pin config settings per pin\n");
seq_puts(s, "Format: pin (name): configs\n");
......@@ -356,9 +347,6 @@ static int pinconf_groups_show(struct seq_file *s, void *what)
unsigned ngroups = pctlops->get_groups_count(pctldev);
unsigned selector = 0;
if (!ops || !ops->pin_config_group_get)
return 0;
seq_puts(s, "Pin config settings per pin group\n");
seq_puts(s, "Format: group (name): configs\n");
......
......@@ -118,7 +118,7 @@ struct at91_pin_group {
};
/**
* struct at91_pinctrl_mux_ops - describes an At91 mux ops group
* struct at91_pinctrl_mux_ops - describes an AT91 mux ops group
* on new IP with support for periph C and D the way to mux in
* periph A and B has changed
* So provide the right call back
......@@ -722,7 +722,8 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev,
unsigned pin;
int div;
dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, *config);
*config = 0;
dev_dbg(info->dev, "%s:%d, pin_id=%d", __func__, __LINE__, pin_id);
pio = pin_to_controller(info, pin_to_bank(pin_id));
pin = pin_id % MAX_NB_GPIO_PER_BANK;
......@@ -1396,7 +1397,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
chained_irq_enter(chip, desc);
for (;;) {
/* Reading ISR acks pending (edge triggered) GPIO interrupts.
* When there none are pending, we're finished unless we need
* When there are none pending, we're finished unless we need
* to process multiple banks (like ID_PIOCDE on sam9263).
*/
isr = readl_relaxed(pio + PIO_ISR) & readl_relaxed(pio + PIO_IMR);
......@@ -1505,7 +1506,7 @@ static int at91_gpio_of_irq_setup(struct device_node *node,
prev = gpio_chips[at91_gpio->pioc_idx - 1];
/* The top level handler handles one bank of GPIOs, except
* on some SoC it can handles up to three...
* on some SoC it can handle up to three...
* We only set up the handler for the first of the list.
*/
if (prev && prev->next == at91_gpio)
......
......@@ -286,13 +286,19 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
spin_lock_irqsave(&vg->lock, flags);
for (i = 0; i < vg->chip.ngpio; i++) {
const char *label;
offs = vg->range->pins[i] * 16;
conf0 = readl(vg->reg_base + offs + BYT_CONF0_REG);
val = readl(vg->reg_base + offs + BYT_VAL_REG);
label = gpiochip_is_requested(chip, i);
if (!label)
label = "Unrequested";
seq_printf(s,
" gpio-%-3d %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s\n",
" gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s\n",
i,
label,
val & BYT_INPUT_EN ? " " : "in",
val & BYT_OUTPUT_EN ? " " : "out",
val & BYT_LEVEL ? "hi" : "lo",
......@@ -366,11 +372,33 @@ static void byt_irq_mask(struct irq_data *d)
{
}
static unsigned int byt_irq_startup(struct irq_data *d)
{
struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
if (gpio_lock_as_irq(&vg->chip, irqd_to_hwirq(d)))
dev_err(vg->chip.dev,
"unable to lock HW IRQ %lu for IRQ\n",
irqd_to_hwirq(d));
byt_irq_unmask(d);
return 0;
}
static void byt_irq_shutdown(struct irq_data *d)
{
struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
byt_irq_mask(d);
gpio_unlock_as_irq(&vg->chip, irqd_to_hwirq(d));
}
static struct irq_chip byt_irqchip = {
.name = "BYT-GPIO",
.irq_mask = byt_irq_mask,
.irq_unmask = byt_irq_unmask,
.irq_set_type = byt_irq_type,
.irq_startup = byt_irq_startup,
.irq_shutdown = byt_irq_shutdown,
};
static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
......
......@@ -638,6 +638,13 @@ int imx1_pinctrl_core_probe(struct platform_device *pdev,
return -EINVAL;
}
ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
if (ret) {
pinctrl_unregister(ipctl->pctl);
dev_err(&pdev->dev, "Failed to populate subdevices\n");
return ret;
}
dev_info(&pdev->dev, "initialized IMX pinctrl driver\n");
return 0;
......
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (c) 2013, Sony Mobile Communications AB.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* 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.
*/
#ifndef __PINCTRL_MSM_H__
#define __PINCTRL_MSM_H__
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/machine.h>
/**
* struct msm_function - a pinmux function
* @name: Name of the pinmux function.
* @groups: List of pingroups for this function.
* @ngroups: Number of entries in @groups.
*/
struct msm_function {
const char *name;
const char * const *groups;
unsigned ngroups;
};
/**
* struct msm_pingroup - Qualcomm pingroup definition
* @name: Name of the pingroup.
* @pins: A list of pins assigned to this pingroup.
* @npins: Number of entries in @pins.
* @funcs: A list of pinmux functions that can be selected for
* this group. The index of the selected function is used
* for programming the function selector.
* Entries should be indices into the groups list of the
* struct msm_pinctrl_soc_data.
* @ctl_reg: Offset of the register holding control bits for this group.
* @io_reg: Offset of the register holding input/output bits for this group.
* @intr_cfg_reg: Offset of the register holding interrupt configuration bits.
* @intr_status_reg: Offset of the register holding the status bits for this group.
* @intr_target_reg: Offset of the register specifying routing of the interrupts
* from this group.
* @mux_bit: Offset in @ctl_reg for the pinmux function selection.
* @pull_bit: Offset in @ctl_reg for the bias configuration.
* @drv_bit: Offset in @ctl_reg for the drive strength configuration.
* @oe_bit: Offset in @ctl_reg for controlling output enable.
* @in_bit: Offset in @io_reg for the input bit value.
* @out_bit: Offset in @io_reg for the output bit value.
* @intr_enable_bit: Offset in @intr_cfg_reg for enabling the interrupt for this group.
* @intr_status_bit: Offset in @intr_status_reg for reading and acking the interrupt
* status.
* @intr_target_bit: Offset in @intr_target_reg for configuring the interrupt routing.
* @intr_raw_status_bit: Offset in @intr_cfg_reg for the raw status bit.
* @intr_polarity_bit: Offset in @intr_cfg_reg for specifying polarity of the interrupt.
* @intr_detection_bit: Offset in @intr_cfg_reg for specifying interrupt type.
* @intr_detection_width: Number of bits used for specifying interrupt type,
* Should be 2 for SoCs that can detect both edges in hardware,
* otherwise 1.
*/
struct msm_pingroup {
const char *name;
const unsigned *pins;
unsigned npins;
unsigned funcs[8];
s16 ctl_reg;
s16 io_reg;
s16 intr_cfg_reg;
s16 intr_status_reg;
s16 intr_target_reg;
unsigned mux_bit:5;
unsigned pull_bit:5;
unsigned drv_bit:5;
unsigned oe_bit:5;
unsigned in_bit:5;
unsigned out_bit:5;
unsigned intr_enable_bit:5;
unsigned intr_status_bit:5;
unsigned intr_target_bit:5;
unsigned intr_raw_status_bit:5;
unsigned intr_polarity_bit:5;
unsigned intr_detection_bit:5;
unsigned intr_detection_width:5;
};
/**
* struct msm_pinctrl_soc_data - Qualcomm pin controller driver configuration
* @pins: An array describing all pins the pin controller affects.
* @npins: The number of entries in @pins.
* @functions: An array describing all mux functions the SoC supports.
* @nfunctions: The number of entries in @functions.
* @groups: An array describing all pin groups the pin SoC supports.
* @ngroups: The numbmer of entries in @groups.
* @ngpio: The number of pingroups the driver should expose as GPIOs.
*/
struct msm_pinctrl_soc_data {
const struct pinctrl_pin_desc *pins;
unsigned npins;
const struct msm_function *functions;
unsigned nfunctions;
const struct msm_pingroup *groups;
unsigned ngroups;
unsigned ngpios;
};
int msm_pinctrl_probe(struct platform_device *pdev,
const struct msm_pinctrl_soc_data *soc_data);
int msm_pinctrl_remove(struct platform_device *pdev);
#endif
This diff is collapsed.
......@@ -846,14 +846,14 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s,
(mode < 0) ? "unknown" : modes[mode],
pull ? "pull" : "none");
if (label && !is_out) {
int irq = gpio_to_irq(gpio);
if (!is_out) {
int irq = gpio_to_irq(gpio);
struct irq_desc *desc = irq_to_desc(irq);
/* This races with request_irq(), set_irq_type(),
* and set_irq_wake() ... but those are "rare".
*/
if (irq >= 0 && desc->action) {
if (irq > 0 && desc && desc->action) {
char *trigger;
u32 bitmask = nmk_gpio_get_bitmask(gpio);
......
......@@ -26,29 +26,67 @@
#include "core.h"
static int sh_pfc_ioremap(struct sh_pfc *pfc, struct platform_device *pdev)
static int sh_pfc_map_resources(struct sh_pfc *pfc,
struct platform_device *pdev)
{
unsigned int num_windows = 0;
unsigned int num_irqs = 0;
struct sh_pfc_window *windows;
unsigned int *irqs = NULL;
struct resource *res;
int k;
unsigned int i;
/* Count the MEM and IRQ resources. */
for (i = 0; i < pdev->num_resources; ++i) {
switch (resource_type(&pdev->resource[i])) {
case IORESOURCE_MEM:
num_windows++;
break;
case IORESOURCE_IRQ:
num_irqs++;
break;
}
}
if (pdev->num_resources == 0)
if (num_windows == 0)
return -EINVAL;
pfc->window = devm_kzalloc(pfc->dev, pdev->num_resources *
sizeof(*pfc->window), GFP_NOWAIT);
if (!pfc->window)
/* Allocate memory windows and IRQs arrays. */
windows = devm_kzalloc(pfc->dev, num_windows * sizeof(*windows),
GFP_KERNEL);
if (windows == NULL)
return -ENOMEM;
pfc->num_windows = pdev->num_resources;
pfc->num_windows = num_windows;
pfc->windows = windows;
for (k = 0, res = pdev->resource; k < pdev->num_resources; k++, res++) {
WARN_ON(resource_type(res) != IORESOURCE_MEM);
pfc->window[k].phys = res->start;
pfc->window[k].size = resource_size(res);
pfc->window[k].virt = devm_ioremap_nocache(pfc->dev, res->start,
resource_size(res));
if (!pfc->window[k].virt)
if (num_irqs) {
irqs = devm_kzalloc(pfc->dev, num_irqs * sizeof(*irqs),
GFP_KERNEL);
if (irqs == NULL)
return -ENOMEM;
pfc->num_irqs = num_irqs;
pfc->irqs = irqs;
}
/* Fill them. */
for (i = 0, res = pdev->resource; i < pdev->num_resources; i++, res++) {
switch (resource_type(res)) {
case IORESOURCE_MEM:
windows->phys = res->start;
windows->size = resource_size(res);
windows->virt = devm_ioremap_resource(pfc->dev, res);
if (IS_ERR(windows->virt))
return -ENOMEM;
windows++;
break;
case IORESOURCE_IRQ:
*irqs++ = res->start;
break;
}
}
return 0;
......@@ -62,7 +100,7 @@ static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc,
/* scan through physical windows and convert address */
for (i = 0; i < pfc->num_windows; i++) {
window = pfc->window + i;
window = pfc->windows + i;
if (address < window->phys)
continue;
......@@ -147,7 +185,7 @@ static void sh_pfc_config_reg_helper(struct sh_pfc *pfc,
unsigned long *maskp,
unsigned long *posp)
{
int k;
unsigned int k;
*mapped_regp = sh_pfc_phys_to_virt(pfc, crp->reg);
......@@ -196,7 +234,7 @@ static int sh_pfc_get_config_reg(struct sh_pfc *pfc, u16 enum_id,
{
const struct pinmux_cfg_reg *config_reg;
unsigned long r_width, f_width, curr_width, ncomb;
int k, m, n, pos, bit_pos;
unsigned int k, m, n, pos, bit_pos;
k = 0;
while (1) {
......@@ -238,7 +276,7 @@ static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, u16 mark, int pos,
u16 *enum_idp)
{
const u16 *data = pfc->info->gpio_data;
int k;
unsigned int k;
if (pos) {
*enum_idp = data[pos + 1];
......@@ -481,7 +519,7 @@ static int sh_pfc_probe(struct platform_device *pdev)
pfc->info = info;
pfc->dev = &pdev->dev;
ret = sh_pfc_ioremap(pfc, pdev);
ret = sh_pfc_map_resources(pfc, pdev);
if (unlikely(ret < 0))
return ret;
......
......@@ -37,7 +37,9 @@ struct sh_pfc {
spinlock_t lock;
unsigned int num_windows;
struct sh_pfc_window *window;
struct sh_pfc_window *windows;
unsigned int num_irqs;
unsigned int *irqs;
struct sh_pfc_pin_range *ranges;
unsigned int nr_ranges;
......
......@@ -204,18 +204,24 @@ static void gpio_pin_set(struct gpio_chip *gc, unsigned offset, int value)
static int gpio_pin_to_irq(struct gpio_chip *gc, unsigned offset)
{
struct sh_pfc *pfc = gpio_to_pfc(gc);
int i, k;
unsigned int i, k;
for (i = 0; i < pfc->info->gpio_irq_size; i++) {
unsigned short *gpios = pfc->info->gpio_irq[i].gpios;
short *gpios = pfc->info->gpio_irq[i].gpios;
for (k = 0; gpios[k]; k++) {
for (k = 0; gpios[k] >= 0; k++) {
if (gpios[k] == offset)
return pfc->info->gpio_irq[i].irq;
goto found;
}
}
return -ENOSYS;
found:
if (pfc->num_irqs)
return pfc->irqs[i];
else
return pfc->info->gpio_irq[i].irq;
}
static int gpio_pin_setup(struct sh_pfc_chip *chip)
......@@ -347,7 +353,7 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
* GPIOs.
*/
for (i = 0; i < pfc->num_windows; ++i) {
struct sh_pfc_window *window = &pfc->window[i];
struct sh_pfc_window *window = &pfc->windows[i];
if (pfc->info->data_regs[0].reg >= window->phys &&
pfc->info->data_regs[0].reg < window->phys + window->size)
......@@ -357,8 +363,14 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
if (i == pfc->num_windows)
return 0;
/* If we have IRQ resources make sure their number is correct. */
if (pfc->num_irqs && pfc->num_irqs != pfc->info->gpio_irq_size) {
dev_err(pfc->dev, "invalid number of IRQ resources\n");
return -EINVAL;
}
/* Register the real GPIOs chip. */
chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup, &pfc->window[i]);
chip = sh_pfc_add_gpiochip(pfc, gpio_pin_setup, &pfc->windows[i]);
if (IS_ERR(chip))
return PTR_ERR(chip);
......
......@@ -2061,17 +2061,6 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(sdhi2),
};
#undef PORTCR
#define PORTCR(nr, reg) \
{ \
PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
_PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
PORT##nr##_FN0, PORT##nr##_FN1, \
PORT##nr##_FN2, PORT##nr##_FN3, \
PORT##nr##_FN4, PORT##nr##_FN5, \
PORT##nr##_FN6, PORT##nr##_FN7 } \
}
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xe6050000),
PORTCR(1, 0xe6050001),
......@@ -2691,7 +2680,7 @@ static unsigned int r8a73a4_pinmux_get_bias(struct sh_pfc *pfc,
{
void __iomem *addr;
addr = pfc->window->virt + r8a73a4_portcr_offsets[pin >> 5] + pin;
addr = pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin;
switch (ioread8(addr) & PORTCR_PULMD_MASK) {
case PORTCR_PULMD_UP:
......@@ -2710,7 +2699,7 @@ static void r8a73a4_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
void __iomem *addr;
u32 value;
addr = pfc->window->virt + r8a73a4_portcr_offsets[pin >> 5] + pin;
addr = pfc->windows->virt + r8a73a4_portcr_offsets[pin >> 5] + pin;
value = ioread8(addr) & ~PORTCR_PULMD_MASK;
switch (bias) {
......
......@@ -3234,17 +3234,6 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(tpu0),
};
#undef PORTCR
#define PORTCR(nr, reg) \
{ \
PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
_PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
PORT##nr##_FN0, PORT##nr##_FN1, \
PORT##nr##_FN2, PORT##nr##_FN3, \
PORT##nr##_FN4, PORT##nr##_FN5, \
PORT##nr##_FN6, PORT##nr##_FN7 } \
}
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xe6050000), /* PORT0CR */
PORTCR(1, 0xe6050001), /* PORT1CR */
......@@ -3721,7 +3710,7 @@ static void __iomem *r8a7740_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin)
&r8a7740_portcr_offsets[i];
if (i <= group->end_pin)
return pfc->window->virt + group->offset + pin;
return pfc->windows->virt + group->offset + pin;
}
return NULL;
......
This diff is collapsed.
......@@ -1730,11 +1730,11 @@ static const unsigned int du_clk_out_1_pins[] = {
static const unsigned int du_clk_out_1_mux[] = {
DU1_DOTCLKOUT1_MARK
};
static const unsigned int du_sync_1_pins[] = {
static const unsigned int du_sync_pins[] = {
/* EXVSYNC/VSYNC, EXHSYNC/HSYNC, EXDISP/EXODDF/EXCDE */
RCAR_GP_PIN(3, 29), RCAR_GP_PIN(3, 28), RCAR_GP_PIN(3, 27),
};
static const unsigned int du_sync_1_mux[] = {
static const unsigned int du_sync_mux[] = {
DU1_EXODDF_DU1_ODDF_DISP_CDE_MARK,
DU1_EXVSYNC_DU1_VSYNC_MARK, DU1_EXHSYNC_DU1_HSYNC_MARK
};
......@@ -1742,6 +1742,9 @@ static const unsigned int du_cde_disp_pins[] = {
/* CDE DISP */
RCAR_GP_PIN(3, 31), RCAR_GP_PIN(3, 30),
};
static const unsigned int du_cde_disp_mux[] = {
DU1_CDE_MARK, DU1_DISP_MARK
};
static const unsigned int du0_clk_in_pins[] = {
/* CLKIN */
RCAR_GP_PIN(6, 31),
......@@ -1749,15 +1752,26 @@ static const unsigned int du0_clk_in_pins[] = {
static const unsigned int du0_clk_in_mux[] = {
DU0_DOTCLKIN_MARK
};
static const unsigned int du_cde_disp_mux[] = {
DU1_CDE_MARK, DU1_DISP_MARK
};
static const unsigned int du1_clk_in_pins[] = {
/* CLKIN */
RCAR_GP_PIN(7, 20), RCAR_GP_PIN(7, 19), RCAR_GP_PIN(3, 24),
RCAR_GP_PIN(3, 24),
};
static const unsigned int du1_clk_in_mux[] = {
DU1_DOTCLKIN_C_MARK, DU1_DOTCLKIN_B_MARK, DU1_DOTCLKIN_MARK
DU1_DOTCLKIN_MARK
};
static const unsigned int du1_clk_in_b_pins[] = {
/* CLKIN */
RCAR_GP_PIN(7, 19),
};
static const unsigned int du1_clk_in_b_mux[] = {
DU1_DOTCLKIN_B_MARK,
};
static const unsigned int du1_clk_in_c_pins[] = {
/* CLKIN */
RCAR_GP_PIN(7, 20),
};
static const unsigned int du1_clk_in_c_mux[] = {
DU1_DOTCLKIN_C_MARK,
};
/* - ETH -------------------------------------------------------------------- */
static const unsigned int eth_link_pins[] = {
......@@ -2670,10 +2684,12 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(du_rgb888),
SH_PFC_PIN_GROUP(du_clk_out_0),
SH_PFC_PIN_GROUP(du_clk_out_1),
SH_PFC_PIN_GROUP(du_sync_1),
SH_PFC_PIN_GROUP(du_sync),
SH_PFC_PIN_GROUP(du_cde_disp),
SH_PFC_PIN_GROUP(du0_clk_in),
SH_PFC_PIN_GROUP(du1_clk_in),
SH_PFC_PIN_GROUP(du1_clk_in_b),
SH_PFC_PIN_GROUP(du1_clk_in_c),
SH_PFC_PIN_GROUP(eth_link),
SH_PFC_PIN_GROUP(eth_magic),
SH_PFC_PIN_GROUP(eth_mdio),
......@@ -2805,7 +2821,7 @@ static const char * const du_groups[] = {
"du_rgb888",
"du_clk_out_0",
"du_clk_out_1",
"du_sync_1",
"du_sync",
"du_cde_disp",
};
......@@ -2815,6 +2831,8 @@ static const char * const du0_groups[] = {
static const char * const du1_groups[] = {
"du1_clk_in",
"du1_clk_in_b",
"du1_clk_in_c",
};
static const char * const eth_groups[] = {
......@@ -2840,20 +2858,29 @@ static const char * const mmc_groups[] = {
static const char * const msiof0_groups[] = {
"msiof0_clk",
"msiof0_ctrl",
"msiof0_data",
"msiof0_sync",
"msiof0_ss1",
"msiof0_ss2",
"msiof0_rx",
"msiof0_tx",
};
static const char * const msiof1_groups[] = {
"msiof1_clk",
"msiof1_ctrl",
"msiof1_data",
"msiof1_sync",
"msiof1_ss1",
"msiof1_ss2",
"msiof1_rx",
"msiof1_tx",
};
static const char * const msiof2_groups[] = {
"msiof2_clk",
"msiof2_ctrl",
"msiof2_data",
"msiof2_sync",
"msiof2_ss1",
"msiof2_ss2",
"msiof2_rx",
"msiof2_tx",
};
static const char * const scif0_groups[] = {
......
......@@ -2118,17 +2118,6 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(usb1),
};
#undef PORTCR
#define PORTCR(nr, reg) \
{ \
PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
_PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
PORT##nr##_FN0, PORT##nr##_FN1, \
PORT##nr##_FN2, PORT##nr##_FN3, \
PORT##nr##_FN4, PORT##nr##_FN5, \
PORT##nr##_FN6, PORT##nr##_FN7 } \
}
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xE6051000), /* PORT0CR */
PORTCR(1, 0xE6051001), /* PORT1CR */
......@@ -2585,7 +2574,7 @@ static void __iomem *sh7372_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin)
&sh7372_portcr_offsets[i];
if (i <= group->end_pin)
return pfc->window->virt + group->offset + pin;
return pfc->windows->virt + group->offset + pin;
}
return NULL;
......
......@@ -3138,16 +3138,6 @@ static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(usb),
};
#undef PORTCR
#define PORTCR(nr, reg) \
{ \
PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
_PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
PORT##nr##_FN0, PORT##nr##_FN1, \
PORT##nr##_FN2, PORT##nr##_FN3, \
PORT##nr##_FN4, PORT##nr##_FN5, \
PORT##nr##_FN6, PORT##nr##_FN7 } \
}
static const struct pinmux_cfg_reg pinmux_config_regs[] = {
PORTCR(0, 0xe6050000), /* PORT0CR */
PORTCR(1, 0xe6050001), /* PORT1CR */
......@@ -3661,38 +3651,38 @@ static const struct pinmux_data_reg pinmux_data_regs[] = {
};
static const struct pinmux_irq pinmux_irqs[] = {
PINMUX_IRQ(irq_pin(19), 9),
PINMUX_IRQ(irq_pin(1), 10),
PINMUX_IRQ(irq_pin(0), 11),
PINMUX_IRQ(irq_pin(1), 10),
PINMUX_IRQ(irq_pin(2), 149),
PINMUX_IRQ(irq_pin(3), 224),
PINMUX_IRQ(irq_pin(4), 159),
PINMUX_IRQ(irq_pin(5), 227),
PINMUX_IRQ(irq_pin(6), 147),
PINMUX_IRQ(irq_pin(7), 150),
PINMUX_IRQ(irq_pin(8), 223),
PINMUX_IRQ(irq_pin(9), 56, 308),
PINMUX_IRQ(irq_pin(10), 54),
PINMUX_IRQ(irq_pin(11), 238),
PINMUX_IRQ(irq_pin(12), 156),
PINMUX_IRQ(irq_pin(13), 239),
PINMUX_IRQ(irq_pin(14), 251),
PINMUX_IRQ(irq_pin(15), 0),
PINMUX_IRQ(irq_pin(16), 249),
PINMUX_IRQ(irq_pin(17), 234),
PINMUX_IRQ(irq_pin(18), 13),
PINMUX_IRQ(irq_pin(19), 9),
PINMUX_IRQ(irq_pin(20), 14),
PINMUX_IRQ(irq_pin(21), 15),
PINMUX_IRQ(irq_pin(31), 26),
PINMUX_IRQ(irq_pin(30), 27),
PINMUX_IRQ(irq_pin(29), 28),
PINMUX_IRQ(irq_pin(22), 40),
PINMUX_IRQ(irq_pin(23), 53),
PINMUX_IRQ(irq_pin(10), 54),
PINMUX_IRQ(irq_pin(9), 56),
PINMUX_IRQ(irq_pin(24), 118),
PINMUX_IRQ(irq_pin(25), 164),
PINMUX_IRQ(irq_pin(26), 115),
PINMUX_IRQ(irq_pin(27), 116),
PINMUX_IRQ(irq_pin(28), 117),
PINMUX_IRQ(irq_pin(24), 118),
PINMUX_IRQ(irq_pin(6), 147),
PINMUX_IRQ(irq_pin(2), 149),
PINMUX_IRQ(irq_pin(7), 150),
PINMUX_IRQ(irq_pin(12), 156),
PINMUX_IRQ(irq_pin(4), 159),
PINMUX_IRQ(irq_pin(25), 164),
PINMUX_IRQ(irq_pin(8), 223),
PINMUX_IRQ(irq_pin(3), 224),
PINMUX_IRQ(irq_pin(5), 227),
PINMUX_IRQ(irq_pin(17), 234),
PINMUX_IRQ(irq_pin(11), 238),
PINMUX_IRQ(irq_pin(13), 239),
PINMUX_IRQ(irq_pin(16), 249),
PINMUX_IRQ(irq_pin(14), 251),
PINMUX_IRQ(irq_pin(9), 308),
PINMUX_IRQ(irq_pin(29), 28),
PINMUX_IRQ(irq_pin(30), 27),
PINMUX_IRQ(irq_pin(31), 26),
};
/* -----------------------------------------------------------------------------
......@@ -3702,7 +3692,7 @@ static const struct pinmux_irq pinmux_irqs[] = {
static void sh73a0_vccq_mc0_endisable(struct regulator_dev *reg, bool enable)
{
struct sh_pfc *pfc = reg->reg_data;
void __iomem *addr = pfc->window[1].virt + 4;
void __iomem *addr = pfc->windows[1].virt + 4;
unsigned long flags;
u32 value;
......@@ -3735,7 +3725,7 @@ static int sh73a0_vccq_mc0_disable(struct regulator_dev *reg)
static int sh73a0_vccq_mc0_is_enabled(struct regulator_dev *reg)
{
struct sh_pfc *pfc = reg->reg_data;
void __iomem *addr = pfc->window[1].virt + 4;
void __iomem *addr = pfc->windows[1].virt + 4;
unsigned long flags;
u32 value;
......@@ -3794,7 +3784,7 @@ static const unsigned int sh73a0_portcr_offsets[] = {
static unsigned int sh73a0_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin)
{
void __iomem *addr = pfc->window->virt
void __iomem *addr = pfc->windows->virt
+ sh73a0_portcr_offsets[pin >> 5] + pin;
u32 value = ioread8(addr) & PORTnCR_PULMD_MASK;
......@@ -3812,7 +3802,7 @@ static unsigned int sh73a0_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin)
static void sh73a0_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
unsigned int bias)
{
void __iomem *addr = pfc->window->virt
void __iomem *addr = pfc->windows->virt
+ sh73a0_portcr_offsets[pin >> 5] + pin;
u32 value = ioread8(addr) & ~PORTnCR_PULMD_MASK;
......
......@@ -94,11 +94,11 @@ struct pinmux_data_reg {
struct pinmux_irq {
int irq;
unsigned short *gpios;
short *gpios;
};
#define PINMUX_IRQ(irq_nr, ids...) \
{ .irq = irq_nr, .gpios = (unsigned short []) { ids, 0 } } \
{ .irq = irq_nr, .gpios = (short []) { ids, -1 } }
struct pinmux_range {
u16 begin;
......@@ -304,8 +304,7 @@ struct sh_pfc_soc_info {
#define PORTCR(nr, reg) \
{ \
PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
_PCRH(PORT##nr##_IN, PORT##nr##_IN_PD, \
PORT##nr##_IN_PU, PORT##nr##_OUT), \
_PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT), \
PORT##nr##_FN0, PORT##nr##_FN1, \
PORT##nr##_FN2, PORT##nr##_FN3, \
PORT##nr##_FN4, PORT##nr##_FN5, \
......
......@@ -82,8 +82,10 @@
* operation, if several modes of operation are supported these can be
* passed in the argument on a custom form, else just use argument 1
* to indicate low power mode, argument 0 turns low power mode off.
* @PIN_CONFIG_OUTPUT: this will configure the pin in output, use argument
* 1 to indicate high level, argument 0 to indicate low level.
* @PIN_CONFIG_OUTPUT: this will configure the pin as an output. Use argument
* 1 to indicate high level, argument 0 to indicate low level. (Please
* see Documentation/pinctrl.txt, section "GPIO mode pitfalls" for a
* discussion around this parameter.)
* @PIN_CONFIG_END: this is the last enumerator for pin configurations, if
* you need to pass in custom configurations to the pin controller, use
* PIN_CONFIG_END+1 as the base offset.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment