Commit d3e26f2f authored by Barry Song's avatar Barry Song Committed by Linus Walleij

pinctrl: sirf: enable the driver support new SiRFmarco SoC

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: default avatarBarry Song <Baohua.Song@csr.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 06763c74
...@@ -143,8 +143,8 @@ config PINCTRL_SINGLE ...@@ -143,8 +143,8 @@ config PINCTRL_SINGLE
This selects the device tree based generic pinctrl driver. This selects the device tree based generic pinctrl driver.
config PINCTRL_SIRF config PINCTRL_SIRF
bool "CSR SiRFprimaII pin controller driver" bool "CSR SiRFprimaII/SiRFmarco pin controller driver"
depends on ARCH_PRIMA2 depends on ARCH_SIRF
select PINMUX select PINMUX
config PINCTRL_TEGRA config PINCTRL_TEGRA
......
...@@ -32,10 +32,10 @@ ...@@ -32,10 +32,10 @@
#define SIRFSOC_NUM_PADS 622 #define SIRFSOC_NUM_PADS 622
#define SIRFSOC_RSC_PIN_MUX 0x4 #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_CTRL(g, i) ((g)*0x100 + (i)*4)
#define SIRFSOC_GPIO_DSP_EN0 (0x80) #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_INT_STATUS(g) ((g)*0x100 + 0x8C)
#define SIRFSOC_GPIO_CTL_INTR_LOW_MASK 0x1 #define SIRFSOC_GPIO_CTL_INTR_LOW_MASK 0x1
...@@ -60,6 +60,7 @@ struct sirfsoc_gpio_bank { ...@@ -60,6 +60,7 @@ struct sirfsoc_gpio_bank {
int id; int id;
int parent_irq; int parent_irq;
spinlock_t lock; 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]; static struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS];
...@@ -191,6 +192,7 @@ struct sirfsoc_pmx { ...@@ -191,6 +192,7 @@ struct sirfsoc_pmx {
struct pinctrl_dev *pmx; struct pinctrl_dev *pmx;
void __iomem *gpio_virtbase; void __iomem *gpio_virtbase;
void __iomem *rsc_virtbase; void __iomem *rsc_virtbase;
bool is_marco;
}; };
/* SIRFSOC_GPIO_PAD_EN set */ /* SIRFSOC_GPIO_PAD_EN set */
...@@ -1088,12 +1090,21 @@ static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, unsigned selector ...@@ -1088,12 +1090,21 @@ static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, unsigned selector
for (i = 0; i < mux->muxmask_counts; i++) { for (i = 0; i < mux->muxmask_counts; i++) {
u32 muxval; u32 muxval;
muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); if (!spmx->is_marco) {
if (enable) muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
muxval = muxval & ~mask[i].mask; if (enable)
else muxval = muxval & ~mask[i].mask;
muxval = muxval | mask[i].mask; else
writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); 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) { if (mux->funcmask && enable) {
...@@ -1158,9 +1169,14 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, ...@@ -1158,9 +1169,14 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev,
spmx = pinctrl_dev_get_drvdata(pmxdev); spmx = pinctrl_dev_get_drvdata(pmxdev);
muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); if (!spmx->is_marco) {
muxval = muxval | (1 << (offset - range->pin_base)); muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
writel(muxval, 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; return 0;
} }
...@@ -1218,6 +1234,7 @@ static void __iomem *sirfsoc_rsc_of_iomap(void) ...@@ -1218,6 +1234,7 @@ static void __iomem *sirfsoc_rsc_of_iomap(void)
{ {
const struct of_device_id rsc_ids[] = { const struct of_device_id rsc_ids[] = {
{ .compatible = "sirf,prima2-rsc" }, { .compatible = "sirf,prima2-rsc" },
{ .compatible = "sirf,marco-rsc" },
{} {}
}; };
struct device_node *np; struct device_node *np;
...@@ -1259,6 +1276,9 @@ static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev) ...@@ -1259,6 +1276,9 @@ static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev)
goto out_no_rsc_remap; 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 */ /* Now register the pin controller and all pins it handles */
spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx); spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx);
if (!spmx->pmx) { if (!spmx->pmx) {
...@@ -1287,6 +1307,7 @@ static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev) ...@@ -1287,6 +1307,7 @@ static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev)
static const struct of_device_id pinmux_ids[] __devinitconst = { static const struct of_device_id pinmux_ids[] __devinitconst = {
{ .compatible = "sirf,prima2-pinctrl" }, { .compatible = "sirf,prima2-pinctrl" },
{ .compatible = "sirf,marco-pinctrl" },
{} {}
}; };
...@@ -1648,6 +1669,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np) ...@@ -1648,6 +1669,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np)
struct sirfsoc_gpio_bank *bank; struct sirfsoc_gpio_bank *bank;
void *regs; void *regs;
struct platform_device *pdev; struct platform_device *pdev;
bool is_marco = false;
pdev = of_find_device_by_node(np); pdev = of_find_device_by_node(np);
if (!pdev) if (!pdev)
...@@ -1657,6 +1679,9 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np) ...@@ -1657,6 +1679,9 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np)
if (!regs) if (!regs)
return -ENOMEM; return -ENOMEM;
if (of_device_is_compatible(np, "sirf,marco-pinctrl"))
is_marco = 1;
for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
bank = &sgpio_bank[i]; bank = &sgpio_bank[i];
spin_lock_init(&bank->lock); spin_lock_init(&bank->lock);
...@@ -1673,6 +1698,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np) ...@@ -1673,6 +1698,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np)
bank->chip.gc.of_node = np; bank->chip.gc.of_node = np;
bank->chip.regs = regs; bank->chip.regs = regs;
bank->id = i; bank->id = i;
bank->is_marco = is_marco;
bank->parent_irq = platform_get_irq(pdev, i); bank->parent_irq = platform_get_irq(pdev, i);
if (bank->parent_irq < 0) { if (bank->parent_irq < 0) {
err = bank->parent_irq; err = bank->parent_irq;
......
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