]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
pinctrl/nomadik: make independent of prcmu driver
authorJonas Aaberg <jonas.aberg@stericsson.com>
Thu, 25 Oct 2012 06:40:42 +0000 (08:40 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Thu, 8 Nov 2012 12:44:59 +0000 (13:44 +0100)
Currently there are some unnecessary criss-cross
dependencies between the PRCMU driver in MFD and a lot of
other drivers, mainly because other drivers need to poke
around in the PRCM register range.

In cases like this there are actually just a few select
registers that the pinctrl driver need to read/modify/write,
and it turns out that no other driver is actually using
these registers, so there are no concurrency issues
whatsoever.

So: don't let the location of the register range complicate
things, just poke into these registers directly and skip
a layer of indirection.

Cc: Loic Pallardy <loic.pallardy@st.com>
Signed-off-by: Jonas Aaberg <jonas.aberg@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/pinctrl/pinctrl-nomadik-db8500.c
drivers/pinctrl/pinctrl-nomadik-db8540.c
drivers/pinctrl/pinctrl-nomadik-stn8815.c
drivers/pinctrl/pinctrl-nomadik.c
drivers/pinctrl/pinctrl-nomadik.h

index 6de52e7c57f0276052f5846d8186fab673762f73..e73d75e3822e1fb515df9d0f36641d0e9c02f288 100644 (file)
@@ -1230,7 +1230,7 @@ static const u16 db8500_prcm_gpiocr_regs[] = {
        [PRCM_IDX_GPIOCR2] = 0x574,
 };
 
-static const struct nmk_pinctrl_soc_data nmk_db8500_soc = {
+static 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,
@@ -1245,7 +1245,7 @@ static const struct nmk_pinctrl_soc_data nmk_db8500_soc = {
 };
 
 void __devinit
-nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc)
+nmk_pinctrl_db8500_init(struct nmk_pinctrl_soc_data **soc)
 {
        *soc = &nmk_db8500_soc;
 }
index 52fc30181f7ea908848a48a6d095373a1d1619d6..1276ba38af71a5f9b0bef28fdf2680a91c11b3f3 100644 (file)
@@ -1240,7 +1240,7 @@ static const u16 db8540_prcm_gpiocr_regs[] = {
        [PRCM_IDX_GPIOCR3] = 0x2bc,
 };
 
-static const struct nmk_pinctrl_soc_data nmk_db8540_soc = {
+static 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,
@@ -1255,7 +1255,7 @@ static const struct nmk_pinctrl_soc_data nmk_db8540_soc = {
 };
 
 void __devinit
-nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc)
+nmk_pinctrl_db8540_init(struct nmk_pinctrl_soc_data **soc)
 {
        *soc = &nmk_db8540_soc;
 }
index 7d432c3bc3590f2f85f803584a6f0d93d4496eb3..ed5b14407b766a53cac80a5b12540fc881ef66c6 100644 (file)
@@ -339,7 +339,7 @@ static const struct nmk_function nmk_stn8815_functions[] = {
        FUNCTION(i2cusb),
 };
 
-static const struct nmk_pinctrl_soc_data nmk_stn8815_soc = {
+static 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,
@@ -351,7 +351,7 @@ static const struct nmk_pinctrl_soc_data nmk_stn8815_soc = {
 };
 
 void __devinit
-nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc)
+nmk_pinctrl_stn8815_init(struct nmk_pinctrl_soc_data **soc)
 {
        *soc = &nmk_stn8815_soc;
 }
index 22f69375bb3ab98e0ed5f0297fd3ee4acb76ef19..33c614ed9118f02c72c435712c686541c566126b 100644 (file)
 #include <linux/pinctrl/pinconf.h>
 /* Since we request GPIOs from ourself */
 #include <linux/pinctrl/consumer.h>
-/*
- * For the U8500 archs, use the PRCMU register interface, for the older
- * Nomadik, provide some stubs. The functions using these will only be
- * called on the U8500 series.
- */
-#ifdef CONFIG_ARCH_U8500
-#include <linux/mfd/dbx500-prcmu.h>
-#else
-static inline u32 prcmu_read(unsigned int reg) {
-       return 0;
-}
-static inline void prcmu_write(unsigned int reg, u32 value) {}
-static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {}
-#endif
 #include <linux/platform_data/pinctrl-nomadik.h>
 
 #include <asm/mach/irq.h>
@@ -85,7 +71,7 @@ struct nmk_gpio_chip {
 struct nmk_pinctrl {
        struct device *dev;
        struct pinctrl_dev *pctl;
-       const struct nmk_pinctrl_soc_data *soc;
+       struct nmk_pinctrl_soc_data *soc;
 };
 
 static struct nmk_gpio_chip *
@@ -247,6 +233,15 @@ nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset)
        dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio);
 }
 
+static void nmk_write_masked(void __iomem *reg, u32 mask, u32 value)
+{
+       u32 val;
+
+       val = readl(reg);
+       val = ((val & ~mask) | (value & mask));
+       writel(val, reg);
+}
+
 static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
        unsigned offset, unsigned alt_num)
 {
@@ -285,8 +280,8 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
                        if (pin_desc->altcx[i].used == true) {
                                reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
                                bit = pin_desc->altcx[i].control_bit;
-                               if (prcmu_read(reg) & BIT(bit)) {
-                                       prcmu_write_masked(reg, BIT(bit), 0);
+                               if (readl(npct->soc->prcmu_base + reg) & BIT(bit)) {
+                                       nmk_write_masked(npct->soc->prcmu_base + reg, BIT(bit), 0);
                                        dev_dbg(npct->dev,
                                                "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
                                                offset, i+1);
@@ -314,8 +309,8 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
                if (pin_desc->altcx[i].used == true) {
                        reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
                        bit = pin_desc->altcx[i].control_bit;
-                       if (prcmu_read(reg) & BIT(bit)) {
-                               prcmu_write_masked(reg, BIT(bit), 0);
+                       if (readl(npct->soc->prcmu_base + reg) & BIT(bit)) {
+                               nmk_write_masked(npct->soc->prcmu_base + reg, BIT(bit), 0);
                                dev_dbg(npct->dev,
                                        "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
                                        offset, i+1);
@@ -327,7 +322,7 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
        bit = pin_desc->altcx[alt_index].control_bit;
        dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n",
                offset, alt_index+1);
-       prcmu_write_masked(reg, BIT(bit), BIT(bit));
+       nmk_write_masked(npct->soc->prcmu_base + reg, BIT(bit), BIT(bit));
 }
 
 static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
@@ -693,7 +688,7 @@ static int nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio)
                if (pin_desc->altcx[i].used == true) {
                        reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
                        bit = pin_desc->altcx[i].control_bit;
-                       if (prcmu_read(reg) & BIT(bit))
+                       if (readl(npct->soc->prcmu_base + reg) & BIT(bit))
                                return NMK_GPIO_ALT_C+i+1;
                }
        }
@@ -1851,6 +1846,7 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev)
        const struct platform_device_id *platid = platform_get_device_id(pdev);
        struct device_node *np = pdev->dev.of_node;
        struct nmk_pinctrl *npct;
+       struct resource *res;
        unsigned int version = 0;
        int i;
 
@@ -1872,6 +1868,20 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev)
        if (version == PINCTRL_NMK_DB8540)
                nmk_pinctrl_db8540_init(&npct->soc);
 
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res) {
+               npct->soc->prcmu_base = devm_ioremap(&pdev->dev, res->start,
+                                                    resource_size(res));
+               if (!npct->soc->prcmu_base) {
+                       dev_err(&pdev->dev,
+                               "failed to ioremap prcmu registers\n");
+                       return -ENOMEM;
+               }
+       } else {
+               dev_info(&pdev->dev,
+                        "No PRCMU base, assume no ALT-Cx control is available\n");
+       }
+
        /*
         * 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
index bcd4191e10ea8ced278c469799d521e4a82dee65..9dd727a716463d24fe193a8f872a9a1ffe78d0a8 100644 (file)
@@ -125,6 +125,7 @@ struct nmk_pingroup {
  * @altcx_pins:        The pins that support Other alternate-C function on this SoC
  * @npins_altcx: The number of Other alternate-C pins
  * @prcm_gpiocr_registers: The array of PRCM GPIOCR registers on this SoC
+ * @prcmu_base: PRCMU virtual base
  */
 struct nmk_pinctrl_soc_data {
        struct pinctrl_gpio_range *gpio_ranges;
@@ -138,16 +139,17 @@ struct nmk_pinctrl_soc_data {
        const struct prcm_gpiocr_altcx_pin_desc *altcx_pins;
        unsigned npins_altcx;
        const u16 *prcm_gpiocr_registers;
+       void __iomem *prcmu_base;
 };
 
 #ifdef CONFIG_PINCTRL_STN8815
 
-void nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc);
+void nmk_pinctrl_stn8815_init(struct nmk_pinctrl_soc_data **soc);
 
 #else
 
 static inline void
-nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc)
+nmk_pinctrl_stn8815_init(struct nmk_pinctrl_soc_data **soc)
 {
 }
 
@@ -155,12 +157,12 @@ nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc)
 
 #ifdef CONFIG_PINCTRL_DB8500
 
-void nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc);
+void nmk_pinctrl_db8500_init(struct nmk_pinctrl_soc_data **soc);
 
 #else
 
 static inline void
-nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc)
+nmk_pinctrl_db8500_init(struct nmk_pinctrl_soc_data **soc)
 {
 }
 
@@ -168,12 +170,12 @@ nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc)
 
 #ifdef CONFIG_PINCTRL_DB8540
 
-void nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc);
+void nmk_pinctrl_db8540_init(struct nmk_pinctrl_soc_data **soc);
 
 #else
 
 static inline void
-nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc)
+nmk_pinctrl_db8540_init(struct nmk_pinctrl_soc_data **soc)
 {
 }