pinctrl: sirf: enable the driver support new SiRFmarco SoC
authorBarry Song <Baohua.Song@csr.com>
Thu, 27 Sep 2012 09:56:30 +0000 (17:56 +0800)
committerLinus Walleij <linus.walleij@linaro.org>
Sun, 11 Nov 2012 18:05:58 +0000 (19:05 +0100)
The driver supports old up SiRFprimaII SoCs, this patch makes it support
the new SiRFmarco as well.
SiRFmarco, as a SMP SoC, adds new SIRFSOC_GPIO_PAD_EN_CLR registers, to
disable GPIO pad, we should write 1 to the corresponding bit in the new
CLEAR register instead of writing 0 to SIRFSOC_GPIO_PAD_EN.

Signed-off-by: Barry Song <Baohua.Song@csr.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/pinctrl/Kconfig
drivers/pinctrl/pinctrl-sirf.c

index 011133772d2a43b75446d24b34022d8e75e3b102..5f2f9dc43e3bca1a66910721276dc45059d69e60 100644 (file)
@@ -143,8 +143,8 @@ config PINCTRL_SINGLE
          This selects the device tree based generic pinctrl driver.
 
 config PINCTRL_SIRF
-       bool "CSR SiRFprimaII pin controller driver"
-       depends on ARCH_PRIMA2
+       bool "CSR SiRFprimaII/SiRFmarco pin controller driver"
+       depends on ARCH_SIRF
        select PINMUX
 
 config PINCTRL_TEGRA
index 9ecacf3d0a759715db3d1081677747b51905626f..16ec7d4d81ee0761daefeddfb2d32bfa2f51dcf1 100644 (file)
 #define SIRFSOC_NUM_PADS    622
 #define SIRFSOC_RSC_PIN_MUX 0x4
 
-#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84)
+#define SIRFSOC_GPIO_PAD_EN(g)         ((g)*0x100 + 0x84)
+#define SIRFSOC_GPIO_PAD_EN_CLR(g)     ((g)*0x100 + 0x90)
 #define SIRFSOC_GPIO_CTRL(g, i)                        ((g)*0x100 + (i)*4)
 #define SIRFSOC_GPIO_DSP_EN0                   (0x80)
-#define SIRFSOC_GPIO_PAD_EN(g)                 ((g)*0x100 + 0x84)
 #define SIRFSOC_GPIO_INT_STATUS(g)             ((g)*0x100 + 0x8C)
 
 #define SIRFSOC_GPIO_CTL_INTR_LOW_MASK         0x1
@@ -60,6 +60,7 @@ struct sirfsoc_gpio_bank {
        int id;
        int parent_irq;
        spinlock_t lock;
+       bool is_marco; /* for marco, some registers are different with prima2 */
 };
 
 static struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS];
@@ -191,6 +192,7 @@ struct sirfsoc_pmx {
        struct pinctrl_dev *pmx;
        void __iomem *gpio_virtbase;
        void __iomem *rsc_virtbase;
+       bool is_marco;
 };
 
 /* SIRFSOC_GPIO_PAD_EN set */
@@ -1088,12 +1090,21 @@ static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, unsigned selector
 
        for (i = 0; i < mux->muxmask_counts; i++) {
                u32 muxval;
-               muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
-               if (enable)
-                       muxval = muxval & ~mask[i].mask;
-               else
-                       muxval = muxval | mask[i].mask;
-               writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
+               if (!spmx->is_marco) {
+                       muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
+                       if (enable)
+                               muxval = muxval & ~mask[i].mask;
+                       else
+                               muxval = muxval | mask[i].mask;
+                       writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
+               } else {
+                       if (enable)
+                               writel(mask[i].mask, spmx->gpio_virtbase +
+                                       SIRFSOC_GPIO_PAD_EN_CLR(mask[i].group));
+                       else
+                               writel(mask[i].mask, spmx->gpio_virtbase +
+                                       SIRFSOC_GPIO_PAD_EN(mask[i].group));
+               }
        }
 
        if (mux->funcmask && enable) {
@@ -1158,9 +1169,14 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev,
 
        spmx = pinctrl_dev_get_drvdata(pmxdev);
 
-       muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
-       muxval = muxval | (1 << (offset - range->pin_base));
-       writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
+       if (!spmx->is_marco) {
+               muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
+               muxval = muxval | (1 << (offset - range->pin_base));
+               writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
+       } else {
+               writel(1 << (offset - range->pin_base), spmx->gpio_virtbase +
+                       SIRFSOC_GPIO_PAD_EN(group));
+       }
 
        return 0;
 }
@@ -1218,6 +1234,7 @@ static void __iomem *sirfsoc_rsc_of_iomap(void)
 {
        const struct of_device_id rsc_ids[]  = {
                { .compatible = "sirf,prima2-rsc" },
+               { .compatible = "sirf,marco-rsc" },
                {}
        };
        struct device_node *np;
@@ -1259,6 +1276,9 @@ static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev)
                goto out_no_rsc_remap;
        }
 
+       if (of_device_is_compatible(np, "sirf,marco-pinctrl"))
+               spmx->is_marco = 1;
+
        /* Now register the pin controller and all pins it handles */
        spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx);
        if (!spmx->pmx) {
@@ -1287,6 +1307,7 @@ out_no_gpio_remap:
 
 static const struct of_device_id pinmux_ids[] __devinitconst = {
        { .compatible = "sirf,prima2-pinctrl" },
+       { .compatible = "sirf,marco-pinctrl" },
        {}
 };
 
@@ -1648,6 +1669,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np)
        struct sirfsoc_gpio_bank *bank;
        void *regs;
        struct platform_device *pdev;
+       bool is_marco = false;
 
        pdev = of_find_device_by_node(np);
        if (!pdev)
@@ -1657,6 +1679,9 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np)
        if (!regs)
                return -ENOMEM;
 
+       if (of_device_is_compatible(np, "sirf,marco-pinctrl"))
+               is_marco = 1;
+
        for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
                bank = &sgpio_bank[i];
                spin_lock_init(&bank->lock);
@@ -1673,6 +1698,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np)
                bank->chip.gc.of_node = np;
                bank->chip.regs = regs;
                bank->id = i;
+               bank->is_marco = is_marco;
                bank->parent_irq = platform_get_irq(pdev, i);
                if (bank->parent_irq < 0) {
                        err = bank->parent_irq;
This page took 0.03028 seconds and 5 git commands to generate.