summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pinctrl/sh-pfc/core.c22
-rw-r--r--drivers/pinctrl/sh-pfc/gpio.c8
-rw-r--r--drivers/pinctrl/sh-pfc/pfc-r8a7778.c13
-rw-r--r--drivers/pinctrl/sh-pfc/pfc-sh73a0.c15
-rw-r--r--drivers/pinctrl/sh-pfc/sh_pfc.h9
5 files changed, 49 insertions, 18 deletions
diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c
index cb47bcee0aab..9e66614bbbb3 100644
--- a/drivers/pinctrl/sh-pfc/core.c
+++ b/drivers/pinctrl/sh-pfc/core.c
@@ -362,7 +362,10 @@ static int sh_pfc_init_ranges(struct sh_pfc *pfc)
return 0;
}
- /* Count, allocate and fill the ranges. */
+ /* Count, allocate and fill the ranges. The PFC SoC data pins array must
+ * be sorted by pin numbers, and pins without a GPIO port must come
+ * last.
+ */
for (i = 1, nr_ranges = 1; i < pfc->info->nr_pins; ++i) {
if (pfc->info->pins[i-1].pin != pfc->info->pins[i].pin - 1)
nr_ranges++;
@@ -378,15 +381,20 @@ static int sh_pfc_init_ranges(struct sh_pfc *pfc)
range->start = pfc->info->pins[0].pin;
for (i = 1; i < pfc->info->nr_pins; ++i) {
- if (pfc->info->pins[i-1].pin != pfc->info->pins[i].pin - 1) {
- range->end = pfc->info->pins[i-1].pin;
- range++;
- range->start = pfc->info->pins[i].pin;
- }
+ if (pfc->info->pins[i-1].pin == pfc->info->pins[i].pin - 1)
+ continue;
+
+ range->end = pfc->info->pins[i-1].pin;
+ if (!(pfc->info->pins[i-1].configs & SH_PFC_PIN_CFG_NO_GPIO))
+ pfc->nr_gpio_pins = range->end + 1;
+
+ range++;
+ range->start = pfc->info->pins[i].pin;
}
range->end = pfc->info->pins[i-1].pin;
- pfc->nr_gpio_pins = range->end + 1;
+ if (!(pfc->info->pins[i-1].configs & SH_PFC_PIN_CFG_NO_GPIO))
+ pfc->nr_gpio_pins = range->end + 1;
return 0;
}
diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c
index 78fcb8029afd..04bf52b64fb3 100644
--- a/drivers/pinctrl/sh-pfc/gpio.c
+++ b/drivers/pinctrl/sh-pfc/gpio.c
@@ -364,10 +364,16 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
pfc->gpio = chip;
- /* Register the GPIO to pin mappings. */
+ /* Register the GPIO to pin mappings. As pins with GPIO ports must come
+ * first in the ranges, skip the pins without GPIO ports by stopping at
+ * the first range that contains such a pin.
+ */
for (i = 0; i < pfc->nr_ranges; ++i) {
const struct sh_pfc_pin_range *range = &pfc->ranges[i];
+ if (range->start >= pfc->nr_gpio_pins)
+ break;
+
ret = gpiochip_add_pin_range(&chip->gpio_chip,
dev_name(pfc->dev),
range->start, range->start,
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7778.c b/drivers/pinctrl/sh-pfc/pfc-r8a7778.c
index 40aecfee1581..428d2a6857ef 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a7778.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a7778.c
@@ -1254,16 +1254,21 @@ static const u16 pinmux_data[] = {
PINMUX_IPSR_MSEL(IP10_24_22, CAN_CLK_C, SEL_CANCLK_C),
};
-static struct sh_pfc_pin pinmux_pins[] = {
- PINMUX_GPIO_GP_ALL(),
-};
-
/* Pin numbers for pins without a corresponding GPIO port number are computed
* from the row and column numbers with a 1000 offset to avoid collisions with
* GPIO port numbers.
*/
#define PIN_NUMBER(row, col) (1000+((row)-1)*25+(col)-1)
+static struct sh_pfc_pin pinmux_pins[] = {
+ PINMUX_GPIO_GP_ALL(),
+
+ /* Pins not associated with a GPIO port */
+ SH_PFC_PIN_NAMED(3, 20, C20),
+ SH_PFC_PIN_NAMED(20, 1, T1),
+ SH_PFC_PIN_NAMED(25, 2, Y2),
+};
+
/* - macro */
#define SH_PFC_PINS(name, args...) \
static const unsigned int name ##_pins[] = { args }
diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c
index 1f4dbe45737a..6417be5514e2 100644
--- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c
+++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c
@@ -1173,6 +1173,12 @@ static const u16 pinmux_data[] = {
#define SH73A0_PIN_IO_PU_PD(pin) SH_PFC_PIN_CFG(pin, __IO | __PUD)
#define SH73A0_PIN_O(pin) SH_PFC_PIN_CFG(pin, __O)
+/* Pin numbers for pins without a corresponding GPIO port number are computed
+ * from the row and column numbers with a 1000 offset to avoid collisions with
+ * GPIO port numbers.
+ */
+#define PIN_NUMBER(row, col) (1000+((row)-1)*34+(col)-1)
+
static struct sh_pfc_pin pinmux_pins[] = {
/* Table 25-1 (I/O and Pull U/D) */
SH73A0_PIN_I_PD(0),
@@ -1444,13 +1450,10 @@ static struct sh_pfc_pin pinmux_pins[] = {
SH73A0_PIN_O(307),
SH73A0_PIN_I_PU(308),
SH73A0_PIN_O(309),
-};
-/* Pin numbers for pins without a corresponding GPIO port number are computed
- * from the row and column numbers with a 1000 offset to avoid collisions with
- * GPIO port numbers.
- */
-#define PIN_NUMBER(row, col) (1000+((row)-1)*34+(col)-1)
+ /* Pins not associated with a GPIO port */
+ SH_PFC_PIN_NAMED(6, 26, F26),
+};
/* - BSC -------------------------------------------------------------------- */
static const unsigned int bsc_data_0_7_pins[] = {
diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h
index 2469b35cfda7..11bd0d970a52 100644
--- a/drivers/pinctrl/sh-pfc/sh_pfc.h
+++ b/drivers/pinctrl/sh-pfc/sh_pfc.h
@@ -26,6 +26,7 @@ enum {
#define SH_PFC_PIN_CFG_OUTPUT (1 << 1)
#define SH_PFC_PIN_CFG_PULL_UP (1 << 2)
#define SH_PFC_PIN_CFG_PULL_DOWN (1 << 3)
+#define SH_PFC_PIN_CFG_NO_GPIO (1 << 31)
struct sh_pfc_pin {
u16 pin;
@@ -266,6 +267,14 @@ struct sh_pfc_soc_info {
.configs = cfgs, \
}
+/* SH_PFC_PIN_NAMED - Expand to a sh_pfc_pin entry with the given name */
+#define SH_PFC_PIN_NAMED(row, col, _name) \
+ { \
+ .pin = PIN_NUMBER(row, col), \
+ .name = __stringify(PIN_##_name), \
+ .configs = SH_PFC_PIN_CFG_NO_GPIO, \
+ }
+
/* PINMUX_DATA_ALL - Expand to a list of PORT_name_DATA, PORT_name_FN0,
* PORT_name_OUT, PORT_name_IN marks
*/
OpenPOWER on IntegriCloud