summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/nomadik
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-09-04 19:22:09 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-04 19:22:09 +0200
commit88a99886c26fec8bf662e7b6bc080431a8660326 (patch)
tree615b9a9a959ab093f6d8d0dd94d3bbc5299fc4c6 /drivers/pinctrl/nomadik
parentMerge tag 'gpio-v4.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linu... (diff)
parentpinctrl: at91: fix null pointer dereference (diff)
downloadlinux-88a99886c26fec8bf662e7b6bc080431a8660326.tar.xz
linux-88a99886c26fec8bf662e7b6bc080431a8660326.zip
Merge tag 'pinctrl-v4.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control updates from Linus Walleij: "This is the bulk of pin control changes for the v4.3 development cycle. Like with GPIO it's a lot of stuff. If my subsystems are any sign of the overall tempo of the kernel v4.3 will be a gigantic diff. [ It looks like 4.3 is calmer than 4.2 in most other subsystems, but we'll see - Linus ] Core changes: - It is possible configure groups in debugfs. - Consolidation of chained IRQ handler install/remove replacing all call sites where irq_set_handler_data() and irq_set_chained_handler() were done in succession with a combined call to irq_set_chained_handler_and_data(). This series was created by Thomas Gleixner after the problem was observed by Russell King. - Tglx also made another series of patches switching __irq_set_handler_locked() for irq_set_handler_locked() which is way cleaner. - Tglx also wrote a good bunch of patches to make use of irq_desc_get_xxx() accessors and avoid looking up irq_descs from IRQ numbers. The goal is to get rid of the irq number from the handlers in the IRQ flow which is nice. Driver feature enhancements: - Power management support for the SiRF SoC Atlas 7. - Power down support for the Qualcomm driver. - Intel Cherryview and Baytrail: switch drivers to use raw spinlocks in IRQ handlers to play nice with the realtime patch set. - Rework and new modes handling for Qualcomm SPMI-MPP. - Pinconf power source config for SH PFC. New drivers and subdrivers: - A new driver for Conexant Digicolor CX92755. - A new driver for UniPhier PH1-LD4, PH1-Pro4, PH1-sLD8, PH1-Pro5, ProXtream2 and PH1-LD6b SoC pin control support. - Reverse-egineered the S/PDIF settings for the Allwinner sun4i driver. - Support for Qualcomm Technologies QDF2xxx ARM64 SoCs - A new Freescale i.mx6ul subdriver. Cleanup: - Remove platform data support in a number of SH PFC subdrivers" * tag 'pinctrl-v4.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (95 commits) pinctrl: at91: fix null pointer dereference pinctrl: mediatek: Implement wake handler and suspend resume pinctrl: mediatek: Fix multiple registration issue. pinctrl: sh-pfc: r8a7794: add USB pin groups pinctrl: at91: Use generic irq_{request,release}_resources() pinctrl: cherryview: Use raw_spinlock for locking pinctrl: baytrail: Use raw_spinlock for locking pinctrl: imx6ul: Remove .owner field pinctrl: zynq: Fix typos in smc0_nand_grp and smc0_nor_grp pinctrl: sh-pfc: Implement pinconf power-source param for voltage switching clk: rockchip: add pclk_pd_pmu to the list of rk3288 critical clocks pinctrl: sun4i: add spdif to pin description. pinctrl: atlas7: clear ugly branch statements for pull and drivestrength pinctrl: baytrail: Serialize all register access pinctrl: baytrail: Drop FSF mailing address pinctrl: rockchip: only enable gpio clock when it setting pinctrl/mediatek: fix spelling mistake in dev_err error message pinctrl: cherryview: Serialize all register access pinctrl: UniPhier: PH1-Pro5: add I2C ch6 pin-mux setting pinctrl: nomadik: reflect current input value ...
Diffstat (limited to 'drivers/pinctrl/nomadik')
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c21
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c24
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c30
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik.c241
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik.h4
5 files changed, 147 insertions, 173 deletions
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
index c74840729648..8392083514fb 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
@@ -355,25 +355,6 @@ static const struct pinctrl_pin_desc nmk_db8500_pins[] = {
PINCTRL_PIN(DB8500_PIN_AC27, "GPIO267_AC27"),
};
-#define DB8500_GPIO_RANGE(a, b, c) { .name = "DB8500", .id = a, .base = b, \
- .pin_base = b, .npins = c }
-
-/*
- * This matches the 32-pin gpio chips registered by the GPIO portion. This
- * cannot be const since we assign the struct gpio_chip * pointer at runtime.
- */
-static struct pinctrl_gpio_range nmk_db8500_ranges[] = {
- DB8500_GPIO_RANGE(0, 0, 32),
- DB8500_GPIO_RANGE(1, 32, 5),
- DB8500_GPIO_RANGE(2, 64, 32),
- DB8500_GPIO_RANGE(3, 96, 2),
- DB8500_GPIO_RANGE(4, 128, 32),
- DB8500_GPIO_RANGE(5, 160, 12),
- DB8500_GPIO_RANGE(6, 192, 32),
- DB8500_GPIO_RANGE(7, 224, 7),
- DB8500_GPIO_RANGE(8, 256, 12),
-};
-
/*
* Read the pin group names like this:
* u0_a_1 = first groups of pins for uart0 on alt function a
@@ -1238,8 +1219,6 @@ static const u16 db8500_prcm_gpiocr_regs[] = {
};
static const struct nmk_pinctrl_soc_data nmk_db8500_soc = {
- .gpio_ranges = nmk_db8500_ranges,
- .gpio_num_ranges = ARRAY_SIZE(nmk_db8500_ranges),
.pins = nmk_db8500_pins,
.npins = ARRAY_SIZE(nmk_db8500_pins),
.functions = nmk_db8500_functions,
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c
index d7ba5443bae0..2860eafd1b42 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c
@@ -341,28 +341,6 @@ static const struct pinctrl_pin_desc nmk_db8540_pins[] = {
PINCTRL_PIN(DB8540_PIN_D17, "GPIO267_D17"),
};
-#define DB8540_GPIO_RANGE(a, b, c) { .name = "db8540", .id = a, .base = b, \
- .pin_base = b, .npins = c }
-
-/*
- * This matches the 32-pin gpio chips registered by the GPIO portion. This
- * cannot be const since we assign the struct gpio_chip * pointer at runtime.
- */
-static struct pinctrl_gpio_range nmk_db8540_ranges[] = {
- DB8540_GPIO_RANGE(0, 0, 18),
- DB8540_GPIO_RANGE(0, 22, 7),
- DB8540_GPIO_RANGE(1, 33, 6),
- DB8540_GPIO_RANGE(2, 64, 4),
- DB8540_GPIO_RANGE(2, 70, 18),
- DB8540_GPIO_RANGE(3, 116, 12),
- DB8540_GPIO_RANGE(4, 128, 32),
- DB8540_GPIO_RANGE(5, 160, 9),
- DB8540_GPIO_RANGE(6, 192, 23),
- DB8540_GPIO_RANGE(6, 219, 5),
- DB8540_GPIO_RANGE(7, 224, 9),
- DB8540_GPIO_RANGE(8, 256, 12),
-};
-
/*
* Read the pin group names like this:
* u0_a_1 = first groups of pins for uart0 on alt function a
@@ -1247,8 +1225,6 @@ static const u16 db8540_prcm_gpiocr_regs[] = {
};
static const struct nmk_pinctrl_soc_data nmk_db8540_soc = {
- .gpio_ranges = nmk_db8540_ranges,
- .gpio_num_ranges = ARRAY_SIZE(nmk_db8540_ranges),
.pins = nmk_db8540_pins,
.npins = ARRAY_SIZE(nmk_db8540_pins),
.functions = nmk_db8540_functions,
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
index 2cd71470f270..587b222f12f3 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
@@ -264,20 +264,6 @@ static const struct pinctrl_pin_desc nmk_stn8815_pins[] = {
PINCTRL_PIN(STN8815_PIN_J22, "GPIO123_J22"),
};
-#define STN8815_GPIO_RANGE(a, b, c) { .name = "STN8815", .id = a, .base = b, \
- .pin_base = b, .npins = c }
-
-/*
- * This matches the 32-pin gpio chips registered by the GPIO portion. This
- * cannot be const since we assign the struct gpio_chip * pointer at runtime.
- */
-static struct pinctrl_gpio_range nmk_stn8815_ranges[] = {
- STN8815_GPIO_RANGE(0, 0, 32),
- STN8815_GPIO_RANGE(1, 32, 32),
- STN8815_GPIO_RANGE(2, 64, 32),
- STN8815_GPIO_RANGE(3, 96, 28),
-};
-
/*
* Read the pin group names like this:
* u0_a_1 = first groups of pins for uart0 on alt function a
@@ -285,9 +271,11 @@ static struct pinctrl_gpio_range nmk_stn8815_ranges[] = {
*/
/* Altfunction A */
-static const unsigned u0_a_1_pins[] = { STN8815_PIN_B4, STN8815_PIN_D5,
- STN8815_PIN_C5, STN8815_PIN_A4, STN8815_PIN_B5, STN8815_PIN_D6,
- STN8815_PIN_C6, STN8815_PIN_B6 };
+static const unsigned u0txrx_a_1_pins[] = { STN8815_PIN_B4, STN8815_PIN_D5 };
+static const unsigned u0ctsrts_a_1_pins[] = { STN8815_PIN_C5, STN8815_PIN_B6 };
+/* Modem pins: DCD, DSR, RI, DTR */
+static const unsigned u0modem_a_1_pins[] = { STN8815_PIN_A4, STN8815_PIN_B5,
+ STN8815_PIN_D6, STN8815_PIN_C6 };
static const unsigned mmcsd_a_1_pins[] = { STN8815_PIN_B10, STN8815_PIN_A10,
STN8815_PIN_C11, STN8815_PIN_B11, STN8815_PIN_A11, STN8815_PIN_C12,
STN8815_PIN_B12, STN8815_PIN_A12, STN8815_PIN_C13, STN8815_PIN_C15 };
@@ -304,7 +292,9 @@ static const unsigned i2cusb_b_1_pins[] = { STN8815_PIN_C21, STN8815_PIN_C20 };
.npins = ARRAY_SIZE(a##_pins), .altsetting = b }
static const struct nmk_pingroup nmk_stn8815_groups[] = {
- STN8815_PIN_GROUP(u0_a_1, NMK_GPIO_ALT_A),
+ STN8815_PIN_GROUP(u0txrx_a_1, NMK_GPIO_ALT_A),
+ STN8815_PIN_GROUP(u0ctsrts_a_1, NMK_GPIO_ALT_A),
+ STN8815_PIN_GROUP(u0modem_a_1, NMK_GPIO_ALT_A),
STN8815_PIN_GROUP(mmcsd_a_1, NMK_GPIO_ALT_A),
STN8815_PIN_GROUP(mmcsd_b_1, NMK_GPIO_ALT_B),
STN8815_PIN_GROUP(u1_a_1, NMK_GPIO_ALT_A),
@@ -318,7 +308,7 @@ static const struct nmk_pingroup nmk_stn8815_groups[] = {
#define STN8815_FUNC_GROUPS(a, b...) \
static const char * const a##_groups[] = { b };
-STN8815_FUNC_GROUPS(u0, "u0_a_1");
+STN8815_FUNC_GROUPS(u0, "u0txrx_a_1", "u0ctsrts_a_1", "u0modem_a_1");
STN8815_FUNC_GROUPS(mmcsd, "mmcsd_a_1", "mmcsd_b_1");
STN8815_FUNC_GROUPS(u1, "u1_a_1", "u1_b_1");
STN8815_FUNC_GROUPS(i2c1, "i2c1_a_1");
@@ -342,8 +332,6 @@ static const struct nmk_function nmk_stn8815_functions[] = {
};
static const struct nmk_pinctrl_soc_data nmk_stn8815_soc = {
- .gpio_ranges = nmk_stn8815_ranges,
- .gpio_num_ranges = ARRAY_SIZE(nmk_stn8815_ranges),
.pins = nmk_stn8815_pins,
.npins = ARRAY_SIZE(nmk_stn8815_pins),
.functions = nmk_stn8815_functions,
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index 809d88445db5..352ede13a9e9 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -203,6 +203,7 @@ typedef unsigned long pin_cfg_t;
#define GPIO_BLOCK_SHIFT 5
#define NMK_GPIO_PER_CHIP (1 << GPIO_BLOCK_SHIFT)
+#define NMK_MAX_BANKS DIV_ROUND_UP(ARCH_NR_GPIOS, NMK_GPIO_PER_CHIP)
/* Register in the logic block */
#define NMK_GPIO_DAT 0x00
@@ -282,8 +283,7 @@ struct nmk_pinctrl {
void __iomem *prcm_base;
};
-static struct nmk_gpio_chip *
-nmk_gpio_chips[DIV_ROUND_UP(ARCH_NR_GPIOS, NMK_GPIO_PER_CHIP)];
+static struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS];
static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
@@ -843,10 +843,9 @@ static void nmk_gpio_irq_shutdown(struct irq_data *d)
clk_disable(nmk_chip->clk);
}
-static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc,
- u32 status)
+static void __nmk_gpio_irq_handler(struct irq_desc *desc, u32 status)
{
- struct irq_chip *host_chip = irq_get_chip(irq);
+ struct irq_chip *host_chip = irq_desc_get_chip(desc);
struct gpio_chip *chip = irq_desc_get_handler_data(desc);
chained_irq_enter(host_chip, desc);
@@ -871,17 +870,16 @@ static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
status = readl(nmk_chip->addr + NMK_GPIO_IS);
clk_disable(nmk_chip->clk);
- __nmk_gpio_irq_handler(irq, desc, status);
+ __nmk_gpio_irq_handler(desc, status);
}
-static void nmk_gpio_latent_irq_handler(unsigned int irq,
- struct irq_desc *desc)
+static void nmk_gpio_latent_irq_handler(unsigned int irq, struct irq_desc *desc)
{
struct gpio_chip *chip = irq_desc_get_handler_data(desc);
struct nmk_gpio_chip *nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
u32 status = nmk_chip->get_latent_status(nmk_chip->bank);
- __nmk_gpio_irq_handler(irq, desc, status);
+ __nmk_gpio_irq_handler(desc, status);
}
/* I/O Functions */
@@ -1012,6 +1010,7 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s,
int irq = gpio_to_irq(gpio);
struct irq_desc *desc = irq_to_desc(irq);
int pullidx = 0;
+ int val;
if (pull)
pullidx = data_out ? 1 : 2;
@@ -1021,6 +1020,10 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s,
label ?: "(none)",
pulls[pullidx],
(mode < 0) ? "unknown" : modes[mode]);
+
+ val = nmk_gpio_get_input(chip, offset);
+ seq_printf(s, " VAL %d", val);
+
/*
* This races with request_irq(), set_irq_type(),
* and set_irq_wake() ... but those are "rare".
@@ -1162,29 +1165,90 @@ void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up)
}
}
+/*
+ * We will allocate memory for the state container using devm* allocators
+ * binding to the first device reaching this point, it doesn't matter if
+ * it is the pin controller or GPIO driver. However we need to use the right
+ * platform device when looking up resources so pay attention to pdev.
+ */
+static struct nmk_gpio_chip *nmk_gpio_populate_chip(struct device_node *np,
+ struct platform_device *pdev)
+{
+ struct nmk_gpio_chip *nmk_chip;
+ struct platform_device *gpio_pdev;
+ struct gpio_chip *chip;
+ struct resource *res;
+ struct clk *clk;
+ void __iomem *base;
+ u32 id;
+
+ gpio_pdev = of_find_device_by_node(np);
+ if (!gpio_pdev) {
+ pr_err("populate \"%s\": device not found\n", np->name);
+ return ERR_PTR(-ENODEV);
+ }
+ if (of_property_read_u32(np, "gpio-bank", &id)) {
+ dev_err(&pdev->dev, "populate: gpio-bank property not found\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ /* Already populated? */
+ nmk_chip = nmk_gpio_chips[id];
+ if (nmk_chip)
+ return nmk_chip;
+
+ nmk_chip = devm_kzalloc(&pdev->dev, sizeof(*nmk_chip), GFP_KERNEL);
+ if (!nmk_chip)
+ return ERR_PTR(-ENOMEM);
+
+ nmk_chip->bank = id;
+ chip = &nmk_chip->chip;
+ chip->base = id * NMK_GPIO_PER_CHIP;
+ chip->ngpio = NMK_GPIO_PER_CHIP;
+ chip->label = dev_name(&gpio_pdev->dev);
+ chip->dev = &gpio_pdev->dev;
+
+ res = platform_get_resource(gpio_pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return base;
+ nmk_chip->addr = base;
+
+ clk = clk_get(&gpio_pdev->dev, NULL);
+ if (IS_ERR(clk))
+ return (void *) clk;
+ clk_prepare(clk);
+ nmk_chip->clk = clk;
+
+ BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
+ nmk_gpio_chips[id] = nmk_chip;
+ return nmk_chip;
+}
+
static int nmk_gpio_probe(struct platform_device *dev)
{
struct device_node *np = dev->dev.of_node;
struct nmk_gpio_chip *nmk_chip;
struct gpio_chip *chip;
struct irq_chip *irqchip;
- struct resource *res;
- struct clk *clk;
int latent_irq;
bool supports_sleepmode;
- void __iomem *base;
int irq;
int ret;
+ nmk_chip = nmk_gpio_populate_chip(np, dev);
+ if (IS_ERR(nmk_chip)) {
+ dev_err(&dev->dev, "could not populate nmk chip struct\n");
+ return PTR_ERR(nmk_chip);
+ }
+
if (of_get_property(np, "st,supports-sleepmode", NULL))
supports_sleepmode = true;
else
supports_sleepmode = false;
- if (of_property_read_u32(np, "gpio-bank", &dev->id)) {
- dev_err(&dev->dev, "gpio-bank property not found\n");
- return -EINVAL;
- }
+ /* Correct platform device ID */
+ dev->id = nmk_chip->bank;
irq = platform_get_irq(dev, 0);
if (irq < 0)
@@ -1193,27 +1257,10 @@ static int nmk_gpio_probe(struct platform_device *dev)
/* It's OK for this IRQ not to be present */
latent_irq = platform_get_irq(dev, 1);
- res = platform_get_resource(dev, IORESOURCE_MEM, 0);
- base = devm_ioremap_resource(&dev->dev, res);
- if (IS_ERR(base))
- return PTR_ERR(base);
-
- clk = devm_clk_get(&dev->dev, NULL);
- if (IS_ERR(clk))
- return PTR_ERR(clk);
- clk_prepare(clk);
-
- nmk_chip = devm_kzalloc(&dev->dev, sizeof(*nmk_chip), GFP_KERNEL);
- if (!nmk_chip)
- return -ENOMEM;
-
/*
* The virt address in nmk_chip->addr is in the nomadik register space,
* so we can simply convert the resource address, without remapping
*/
- nmk_chip->bank = dev->id;
- nmk_chip->clk = clk;
- nmk_chip->addr = base;
nmk_chip->parent_irq = irq;
nmk_chip->latent_parent_irq = latent_irq;
nmk_chip->sleepmode = supports_sleepmode;
@@ -1228,10 +1275,6 @@ static int nmk_gpio_probe(struct platform_device *dev)
chip->set = nmk_gpio_set_output;
chip->dbg_show = nmk_gpio_dbg_show;
chip->can_sleep = false;
- chip->base = dev->id * NMK_GPIO_PER_CHIP;
- chip->ngpio = NMK_GPIO_PER_CHIP;
- chip->label = dev_name(&dev->dev);
- chip->dev = &dev->dev;
chip->owner = THIS_MODULE;
irqchip = &nmk_chip->irqchip;
@@ -1253,14 +1296,10 @@ static int nmk_gpio_probe(struct platform_device *dev)
clk_disable(nmk_chip->clk);
chip->of_node = np;
- ret = gpiochip_add(&nmk_chip->chip);
+ ret = gpiochip_add(chip);
if (ret)
return ret;
- BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
-
- nmk_gpio_chips[nmk_chip->bank] = nmk_chip;
-
platform_set_drvdata(dev, nmk_chip);
/*
@@ -1320,35 +1359,40 @@ static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
return 0;
}
-static struct pinctrl_gpio_range *
-nmk_match_gpio_range(struct pinctrl_dev *pctldev, unsigned offset)
+static struct nmk_gpio_chip *find_nmk_gpio_from_pin(unsigned pin)
{
- struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
int i;
+ struct nmk_gpio_chip *nmk_gpio;
- for (i = 0; i < npct->soc->gpio_num_ranges; i++) {
- struct pinctrl_gpio_range *range;
-
- range = &npct->soc->gpio_ranges[i];
- if (offset >= range->pin_base &&
- offset <= (range->pin_base + range->npins - 1))
- return range;
+ for(i = 0; i < NMK_MAX_BANKS; i++) {
+ nmk_gpio = nmk_gpio_chips[i];
+ if (!nmk_gpio)
+ continue;
+ if (pin >= nmk_gpio->chip.base &&
+ pin < nmk_gpio->chip.base + nmk_gpio->chip.ngpio)
+ return nmk_gpio;
}
return NULL;
}
+static struct gpio_chip *find_gc_from_pin(unsigned pin)
+{
+ struct nmk_gpio_chip *nmk_gpio = find_nmk_gpio_from_pin(pin);
+
+ if (nmk_gpio)
+ return &nmk_gpio->chip;
+ return NULL;
+}
+
static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
unsigned offset)
{
- struct pinctrl_gpio_range *range;
- struct gpio_chip *chip;
+ struct gpio_chip *chip = find_gc_from_pin(offset);
- range = nmk_match_gpio_range(pctldev, offset);
- if (!range || !range->gc) {
+ if (!chip) {
seq_printf(s, "invalid pin offset");
return;
}
- chip = range->gc;
nmk_gpio_dbg_show_one(s, pctldev, chip, offset - chip->base, offset);
}
@@ -1693,25 +1737,16 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function,
}
for (i = 0; i < g->npins; i++) {
- struct pinctrl_gpio_range *range;
struct nmk_gpio_chip *nmk_chip;
- struct gpio_chip *chip;
unsigned bit;
- range = nmk_match_gpio_range(pctldev, g->pins[i]);
- if (!range) {
+ nmk_chip = find_nmk_gpio_from_pin(g->pins[i]);
+ if (!nmk_chip) {
dev_err(npct->dev,
"invalid pin offset %d in group %s at index %d\n",
g->pins[i], g->name, i);
goto out_glitch;
}
- if (!range->gc) {
- dev_err(npct->dev, "GPIO chip missing in range for pin offset %d in group %s at index %d\n",
- g->pins[i], g->name, i);
- goto out_glitch;
- }
- chip = range->gc;
- nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
dev_dbg(npct->dev, "setting pin %d to altsetting %d\n", g->pins[i], g->altsetting);
clk_enable(nmk_chip->clk);
@@ -1827,25 +1862,17 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
};
struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
struct nmk_gpio_chip *nmk_chip;
- struct pinctrl_gpio_range *range;
- struct gpio_chip *chip;
unsigned bit;
pin_cfg_t cfg;
int pull, slpm, output, val, i;
bool lowemi, gpiomode, sleep;
- range = nmk_match_gpio_range(pctldev, pin);
- if (!range) {
- dev_err(npct->dev, "invalid pin offset %d\n", pin);
- return -EINVAL;
- }
- if (!range->gc) {
- dev_err(npct->dev, "GPIO chip missing in range for pin %d\n",
- pin);
+ nmk_chip = find_nmk_gpio_from_pin(pin);
+ if (!nmk_chip) {
+ dev_err(npct->dev,
+ "invalid pin offset %d\n", pin);
return -EINVAL;
}
- chip = range->gc;
- nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
for (i = 0; i < num_configs; i++) {
/*
@@ -1997,6 +2024,31 @@ static int nmk_pinctrl_probe(struct platform_device *pdev)
if (version == PINCTRL_NMK_DB8540)
nmk_pinctrl_db8540_init(&npct->soc);
+ /*
+ * Since we depend on the GPIO chips to provide clock and register base
+ * for the pin control operations, make sure that we have these
+ * populated before we continue. Follow the phandles to instantiate
+ * them. The GPIO portion of the actual hardware may be probed before
+ * or after this point: it shouldn't matter as the APIs are orthogonal.
+ */
+ for (i = 0; i < NMK_MAX_BANKS; i++) {
+ struct device_node *gpio_np;
+ struct nmk_gpio_chip *nmk_chip;
+
+ gpio_np = of_parse_phandle(np, "nomadik-gpio-chips", i);
+ if (gpio_np) {
+ dev_info(&pdev->dev,
+ "populate NMK GPIO %d \"%s\"\n",
+ i, gpio_np->name);
+ nmk_chip = nmk_gpio_populate_chip(gpio_np, pdev);
+ if (IS_ERR(nmk_chip))
+ dev_err(&pdev->dev,
+ "could not populate nmk chip struct "
+ "- continue anyway\n");
+ of_node_put(gpio_np);
+ }
+ }
+
prcm_np = of_parse_phandle(np, "prcm", 0);
if (prcm_np)
npct->prcm_base = of_iomap(prcm_np, 0);
@@ -2011,19 +2063,6 @@ static int nmk_pinctrl_probe(struct platform_device *pdev)
}
}
- /*
- * We need all the GPIO drivers to probe FIRST, or we will not be able
- * to obtain references to the struct gpio_chip * for them, and we
- * need this to proceed.
- */
- for (i = 0; i < npct->soc->gpio_num_ranges; i++) {
- if (!nmk_gpio_chips[npct->soc->gpio_ranges[i].id]) {
- dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i);
- return -EPROBE_DEFER;
- }
- npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[npct->soc->gpio_ranges[i].id]->chip;
- }
-
nmk_pinctrl_desc.pins = npct->soc->pins;
nmk_pinctrl_desc.npins = npct->soc->npins;
npct->dev = &pdev->dev;
@@ -2034,10 +2073,6 @@ static int nmk_pinctrl_probe(struct platform_device *pdev)
return PTR_ERR(npct->pctl);
}
- /* We will handle a range of GPIO pins */
- for (i = 0; i < npct->soc->gpio_num_ranges; i++)
- pinctrl_add_gpio_range(npct->pctl, &npct->soc->gpio_ranges[i]);
-
platform_set_drvdata(pdev, npct);
dev_info(&pdev->dev, "initialized Nomadik pin control driver\n");
@@ -2072,15 +2107,15 @@ static struct platform_driver nmk_pinctrl_driver = {
static int __init nmk_gpio_init(void)
{
- int ret;
+ return platform_driver_register(&nmk_gpio_driver);
+}
+subsys_initcall(nmk_gpio_init);
- ret = platform_driver_register(&nmk_gpio_driver);
- if (ret)
- return ret;
+static int __init nmk_pinctrl_init(void)
+{
return platform_driver_register(&nmk_pinctrl_driver);
}
-
-core_initcall(nmk_gpio_init);
+core_initcall(nmk_pinctrl_init);
MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
MODULE_DESCRIPTION("Nomadik GPIO Driver");
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.h b/drivers/pinctrl/nomadik/pinctrl-nomadik.h
index d8215f1e70c7..30bba2a75a58 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.h
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.h
@@ -121,8 +121,6 @@ struct nmk_pingroup {
/**
* struct nmk_pinctrl_soc_data - Nomadik pin controller per-SoC configuration
- * @gpio_ranges: An array of GPIO ranges for this SoC
- * @gpio_num_ranges: The number of GPIO ranges for this SoC
* @pins: An array describing all pins the pin controller affects.
* All pins which are also GPIOs must be listed first within the
* array, and be numbered identically to the GPIO controller's
@@ -137,8 +135,6 @@ struct nmk_pingroup {
* @prcm_gpiocr_registers: The array of PRCM GPIOCR registers on this SoC
*/
struct nmk_pinctrl_soc_data {
- struct pinctrl_gpio_range *gpio_ranges;
- unsigned gpio_num_ranges;
const struct pinctrl_pin_desc *pins;
unsigned npins;
const struct nmk_function *functions;