Commit 13d6a11a authored by Linus Walleij's avatar Linus Walleij

Merge tag 'v3.19-rockchip-pinctrl1' of...

Merge tag 'v3.19-rockchip-pinctrl1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip into devel

Rockchip-pinctrl fixes from Doug Anderson and suspend-specific
functions from Chris Zhong
parents 0c49e2f6 8dca9331
...@@ -856,27 +856,22 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, ...@@ -856,27 +856,22 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
* leads to this function call (via the pinctrl_gpio_direction_{input|output}() * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
* function called from the gpiolib interface). * function called from the gpiolib interface).
*/ */
static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip,
struct pinctrl_gpio_range *range, int pin, bool input)
unsigned offset, bool input)
{ {
struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
struct rockchip_pin_bank *bank; struct rockchip_pin_bank *bank;
struct gpio_chip *chip; int ret;
int pin, ret; unsigned long flags;
u32 data; u32 data;
chip = range->gc;
bank = gc_to_pin_bank(chip); bank = gc_to_pin_bank(chip);
pin = offset - chip->base;
dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n",
offset, range->name, pin, input ? "input" : "output");
ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO); ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO);
if (ret < 0) if (ret < 0)
return ret; return ret;
spin_lock_irqsave(&bank->slock, flags);
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
/* set bit to 1 for output, 0 for input */ /* set bit to 1 for output, 0 for input */
if (!input) if (!input)
...@@ -885,9 +880,28 @@ static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, ...@@ -885,9 +880,28 @@ static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
data &= ~BIT(pin); data &= ~BIT(pin);
writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
spin_unlock_irqrestore(&bank->slock, flags);
return 0; return 0;
} }
static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset, bool input)
{
struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
struct gpio_chip *chip;
int pin;
chip = range->gc;
pin = offset - chip->base;
dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n",
offset, range->name, pin, input ? "input" : "output");
return _rockchip_pmx_gpio_set_direction(chip, offset - chip->base,
input);
}
static const struct pinmux_ops rockchip_pmx_ops = { static const struct pinmux_ops rockchip_pmx_ops = {
.get_functions_count = rockchip_pmx_get_funcs_count, .get_functions_count = rockchip_pmx_get_funcs_count,
.get_function_name = rockchip_pmx_get_func_name, .get_function_name = rockchip_pmx_get_func_name,
...@@ -917,8 +931,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, ...@@ -917,8 +931,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
return false; return false;
} }
static int rockchip_gpio_direction_output(struct gpio_chip *gc, static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value);
unsigned offset, int value);
static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset); static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset);
/* set the pin config settings for a specified pin */ /* set the pin config settings for a specified pin */
...@@ -959,9 +972,10 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -959,9 +972,10 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
return rc; return rc;
break; break;
case PIN_CONFIG_OUTPUT: case PIN_CONFIG_OUTPUT:
rc = rockchip_gpio_direction_output(&bank->gpio_chip, rockchip_gpio_set(&bank->gpio_chip,
pin - bank->pin_base, pin - bank->pin_base, arg);
arg); rc = _rockchip_pmx_gpio_set_direction(&bank->gpio_chip,
pin - bank->pin_base, false);
if (rc) if (rc)
return rc; return rc;
break; break;
...@@ -1253,6 +1267,10 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, ...@@ -1253,6 +1267,10 @@ static int rockchip_pinctrl_register(struct platform_device *pdev,
} }
} }
ret = rockchip_pinctrl_parse_dt(pdev, info);
if (ret)
return ret;
info->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, info); info->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, info);
if (!info->pctl_dev) { if (!info->pctl_dev) {
dev_err(&pdev->dev, "could not register pinctrl driver\n"); dev_err(&pdev->dev, "could not register pinctrl driver\n");
...@@ -1270,12 +1288,6 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, ...@@ -1270,12 +1288,6 @@ static int rockchip_pinctrl_register(struct platform_device *pdev,
pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange); pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange);
} }
ret = rockchip_pinctrl_parse_dt(pdev, info);
if (ret) {
pinctrl_unregister(info->pctl_dev);
return ret;
}
return 0; return 0;
} }
...@@ -1387,6 +1399,7 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) ...@@ -1387,6 +1399,7 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc)
u32 polarity = 0, data = 0; u32 polarity = 0, data = 0;
u32 pend; u32 pend;
bool edge_changed = false; bool edge_changed = false;
unsigned long flags;
dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name);
...@@ -1432,10 +1445,14 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) ...@@ -1432,10 +1445,14 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc)
if (bank->toggle_edge_mode && edge_changed) { if (bank->toggle_edge_mode && edge_changed) {
/* Interrupt params should only be set with ints disabled */ /* Interrupt params should only be set with ints disabled */
spin_lock_irqsave(&bank->slock, flags);
data = readl_relaxed(bank->reg_base + GPIO_INTEN); data = readl_relaxed(bank->reg_base + GPIO_INTEN);
writel_relaxed(0, bank->reg_base + GPIO_INTEN); writel_relaxed(0, bank->reg_base + GPIO_INTEN);
writel(polarity, bank->reg_base + GPIO_INT_POLARITY); writel(polarity, bank->reg_base + GPIO_INT_POLARITY);
writel(data, bank->reg_base + GPIO_INTEN); writel(data, bank->reg_base + GPIO_INTEN);
spin_unlock_irqrestore(&bank->slock, flags);
} }
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
...@@ -1449,6 +1466,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) ...@@ -1449,6 +1466,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
u32 polarity; u32 polarity;
u32 level; u32 level;
u32 data; u32 data;
unsigned long flags;
int ret; int ret;
/* make sure the pin is configured as gpio input */ /* make sure the pin is configured as gpio input */
...@@ -1456,15 +1474,20 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) ...@@ -1456,15 +1474,20 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
if (ret < 0) if (ret < 0)
return ret; return ret;
spin_lock_irqsave(&bank->slock, flags);
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
data &= ~mask; data &= ~mask;
writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
spin_unlock_irqrestore(&bank->slock, flags);
if (type & IRQ_TYPE_EDGE_BOTH) if (type & IRQ_TYPE_EDGE_BOTH)
__irq_set_handler_locked(d->irq, handle_edge_irq); __irq_set_handler_locked(d->irq, handle_edge_irq);
else else
__irq_set_handler_locked(d->irq, handle_level_irq); __irq_set_handler_locked(d->irq, handle_level_irq);
spin_lock_irqsave(&bank->slock, flags);
irq_gc_lock(gc); irq_gc_lock(gc);
level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL); level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL);
...@@ -1507,6 +1530,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) ...@@ -1507,6 +1530,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
break; break;
default: default:
irq_gc_unlock(gc); irq_gc_unlock(gc);
spin_unlock_irqrestore(&bank->slock, flags);
return -EINVAL; return -EINVAL;
} }
...@@ -1514,6 +1538,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) ...@@ -1514,6 +1538,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY); writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY);
irq_gc_unlock(gc); irq_gc_unlock(gc);
spin_unlock_irqrestore(&bank->slock, flags);
return 0; return 0;
} }
...@@ -1563,6 +1588,7 @@ static int rockchip_interrupts_register(struct platform_device *pdev, ...@@ -1563,6 +1588,7 @@ static int rockchip_interrupts_register(struct platform_device *pdev,
gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake;
gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type;
gc->wake_enabled = IRQ_MSK(bank->nr_pins);
irq_set_handler_data(bank->irq, bank); irq_set_handler_data(bank->irq, bank);
irq_set_chained_handler(bank->irq, rockchip_irq_demux); irq_set_chained_handler(bank->irq, rockchip_irq_demux);
...@@ -1770,6 +1796,51 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( ...@@ -1770,6 +1796,51 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
return ctrl; return ctrl;
} }
#define RK3288_GRF_GPIO6C_IOMUX 0x64
#define GPIO6C6_SEL_WRITE_ENABLE BIT(28)
static u32 rk3288_grf_gpio6c_iomux;
static int __maybe_unused rockchip_pinctrl_suspend(struct device *dev)
{
struct rockchip_pinctrl *info = dev_get_drvdata(dev);
int ret = pinctrl_force_sleep(info->pctl_dev);
if (ret)
return ret;
/*
* RK3288 GPIO6_C6 mux would be modified by Maskrom when resume, so save
* the setting here, and restore it at resume.
*/
if (info->ctrl->type == RK3288) {
ret = regmap_read(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX,
&rk3288_grf_gpio6c_iomux);
if (ret) {
pinctrl_force_default(info->pctl_dev);
return ret;
}
}
return 0;
}
static int __maybe_unused rockchip_pinctrl_resume(struct device *dev)
{
struct rockchip_pinctrl *info = dev_get_drvdata(dev);
int ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX,
rk3288_grf_gpio6c_iomux |
GPIO6C6_SEL_WRITE_ENABLE);
if (ret)
return ret;
return pinctrl_force_default(info->pctl_dev);
}
static SIMPLE_DEV_PM_OPS(rockchip_pinctrl_dev_pm_ops, rockchip_pinctrl_suspend,
rockchip_pinctrl_resume);
static int rockchip_pinctrl_probe(struct platform_device *pdev) static int rockchip_pinctrl_probe(struct platform_device *pdev)
{ {
struct rockchip_pinctrl *info; struct rockchip_pinctrl *info;
...@@ -1983,6 +2054,7 @@ static struct platform_driver rockchip_pinctrl_driver = { ...@@ -1983,6 +2054,7 @@ static struct platform_driver rockchip_pinctrl_driver = {
.driver = { .driver = {
.name = "rockchip-pinctrl", .name = "rockchip-pinctrl",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.pm = &rockchip_pinctrl_dev_pm_ops,
.of_match_table = rockchip_pinctrl_dt_match, .of_match_table = rockchip_pinctrl_dt_match,
}, },
}; };
......
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