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: Barry Song <Baohua.Song@csr.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
06763c741b
commit
d3e26f2fe9
|
@ -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
|
||||||
|
|
|
@ -33,9 +33,9 @@
|
||||||
#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 {
|
||||||
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 {
|
||||||
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
|
||||||
|
|
||||||
for (i = 0; i < mux->muxmask_counts; i++) {
|
for (i = 0; i < mux->muxmask_counts; i++) {
|
||||||
u32 muxval;
|
u32 muxval;
|
||||||
|
if (!spmx->is_marco) {
|
||||||
muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
|
muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
|
||||||
if (enable)
|
if (enable)
|
||||||
muxval = muxval & ~mask[i].mask;
|
muxval = muxval & ~mask[i].mask;
|
||||||
else
|
else
|
||||||
muxval = muxval | mask[i].mask;
|
muxval = muxval | mask[i].mask;
|
||||||
writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
|
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,
|
||||||
|
|
||||||
spmx = pinctrl_dev_get_drvdata(pmxdev);
|
spmx = pinctrl_dev_get_drvdata(pmxdev);
|
||||||
|
|
||||||
|
if (!spmx->is_marco) {
|
||||||
muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
|
muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
|
||||||
muxval = muxval | (1 << (offset - range->pin_base));
|
muxval = muxval | (1 << (offset - range->pin_base));
|
||||||
writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
|
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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 @@ out_no_gpio_remap:
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue