Skip to content

Commit

Permalink
pinctrl: sirf: enable the driver support new SiRFmarco SoC
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Barry Song authored and Linus Walleij committed Nov 11, 2012
1 parent 06763c7 commit d3e26f2
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 13 deletions.
4 changes: 2 additions & 2 deletions drivers/pinctrl/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
48 changes: 37 additions & 11 deletions drivers/pinctrl/pinctrl-sirf.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
#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
Expand All @@ -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];
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -1287,6 +1307,7 @@ static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev)

static const struct of_device_id pinmux_ids[] __devinitconst = {
{ .compatible = "sirf,prima2-pinctrl" },
{ .compatible = "sirf,marco-pinctrl" },
{}
};

Expand Down Expand Up @@ -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)
Expand All @@ -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);
Expand All @@ -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;
Expand Down

0 comments on commit d3e26f2

Please sign in to comment.