mirror of
https://github.com/torvalds/linux.git
synced 2026-07-29 10:41:49 +02:00
Pin control fixes for the v7.0 kernel series:
- Implement .get_direction() in the spmi-gpio gpio_chip. Recent changes makes this start to print warnings and it's not nice, let's just fix it. - Clamp the return value of gpio_get() in the Renesas RZA1 driver. - Add the GPIO_GENERIC dependency to the STM32 HDP driver. - Modify the Mediatek driver to accept devices that do not use external interrupts (EINT) at all. - Fix flag propagation in the Sunxi driver, so that we can fix an issue with uninitialized pins in a follow-up patch using said flags. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEElDRnuGcz/wPCXQWMQRCzN7AZXXMFAmnFJ8kACgkQQRCzN7AZ XXPWKxAAomjlOX5/FprpAPQm58K1zBMdJGNrrrKRa/wOt/hNRA5BosP33Mdp+TVJ gIvFZHlwSU8dsqPKH4hjqrgVnS/WcvpLg24O4vpWexl9BvZnlJRb4UdQC0Kkvtu9 mdHo/BLKi5SswQZ2R6xzF8ljtZNCiln0RoKrOzgt2IpKRrv/A19LcUmJ8VPUZ3J1 7yNHfsM/aYTPkQkNx50XAKtfIkSZ34OBo1Y+h72s0LRvoziujcEIbrZXDM1+9lKp vNdbzs75NQqTwNd+HiPK9ydZ5xu5/y9lpguWi5hrpUOGzDnHd3RTSblDtSVeeN0T ERX2f0pKi3qdA4eJ3CQrMOHzIwDbpP9kqQhtUwrV2OqDrwPBn3xFzCIBt+iPA5vk tfP+rtxn+w9DcUNx4Hv1OkTk3wHPPoY7UlBiaCP6Yh6fhjaRTPS03SwXDX49mzwD W8MLKEAM64pdJsSFA5kX6CcETHwl5le1NcS1B8mC9KW9Enw52QBWiaTpJUoMVd6/ tRZCR63phvOSAHtqxcSmgszytmjc5PkbHpziyINISsjCulUPIpO9mDKydNuMo2V3 VSABF5hagFLThgyMXOLEVlK9cAyvx1zw8BpFLBbAVJQ9FHy+Zw4NqlrrCSRMEMvA SEc2DrhXNk8PyfVUJjo8HR2VkZW935lk9oAEQ8KjKupSdj5Duqc= =Ay1e -----END PGP SIGNATURE----- Merge tag 'pinctrl-v7.0-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl Pull pin control fixes from Linus Walleij: - Implement .get_direction() in the spmi-gpio gpio_chip Recent changes makes this start to print warnings and it's not nice, let's just fix it - Clamp the return value of gpio_get() in the Renesas RZA1 driver - Add the GPIO_GENERIC dependency to the STM32 HDP driver - Modify the Mediatek driver to accept devices that do not use external interrupts (EINT) at all - Fix flag propagation in the Sunxi driver, so that we can fix an issue with uninitialized pins in a follow-up patch using said flags * tag 'pinctrl-v7.0-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: pinctrl: sunxi: fix gpiochip_lock_as_irq() failure when pinmux is unknown pinctrl: sunxi: pass down flags to pinctrl routines pinctrl: mediatek: common: Fix probe failure for devices without EINT pinctrl: stm32: fix HDP driver dependency on GPIO_GENERIC pinctrl: renesas: rza1: Normalize return value of gpio_get() pinctrl: qcom: spmi-gpio: implement .get_direction() pinctrl: renesas: rzt2h: Fix invalid wait context pinctrl: renesas: rzt2h: Fix device node leak in rzt2h_gpio_register()
This commit is contained in:
commit
75c78a4faa
|
|
@ -1135,9 +1135,12 @@ int mtk_pctrl_init(struct platform_device *pdev,
|
|||
goto chip_error;
|
||||
}
|
||||
|
||||
ret = mtk_eint_init(pctl, pdev);
|
||||
if (ret)
|
||||
goto chip_error;
|
||||
/* Only initialize EINT if we have EINT pins */
|
||||
if (data->eint_hw.ap_num > 0) {
|
||||
ret = mtk_eint_init(pctl, pdev);
|
||||
if (ret)
|
||||
goto chip_error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -723,6 +723,21 @@ static const struct pinconf_ops pmic_gpio_pinconf_ops = {
|
|||
.pin_config_group_dbg_show = pmic_gpio_config_dbg_show,
|
||||
};
|
||||
|
||||
static int pmic_gpio_get_direction(struct gpio_chip *chip, unsigned pin)
|
||||
{
|
||||
struct pmic_gpio_state *state = gpiochip_get_data(chip);
|
||||
struct pmic_gpio_pad *pad;
|
||||
|
||||
pad = state->ctrl->desc->pins[pin].drv_data;
|
||||
|
||||
if (!pad->is_enabled || pad->analog_pass ||
|
||||
(!pad->input_enabled && !pad->output_enabled))
|
||||
return -EINVAL;
|
||||
|
||||
/* Make sure the state is aligned on what pmic_gpio_get() returns */
|
||||
return pad->input_enabled ? GPIO_LINE_DIRECTION_IN : GPIO_LINE_DIRECTION_OUT;
|
||||
}
|
||||
|
||||
static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
|
||||
{
|
||||
struct pmic_gpio_state *state = gpiochip_get_data(chip);
|
||||
|
|
@ -801,6 +816,7 @@ static void pmic_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
|
|||
}
|
||||
|
||||
static const struct gpio_chip pmic_gpio_gpio_template = {
|
||||
.get_direction = pmic_gpio_get_direction,
|
||||
.direction_input = pmic_gpio_direction_input,
|
||||
.direction_output = pmic_gpio_direction_output,
|
||||
.get = pmic_gpio_get,
|
||||
|
|
|
|||
|
|
@ -589,7 +589,7 @@ static inline unsigned int rza1_get_bit(struct rza1_port *port,
|
|||
{
|
||||
void __iomem *mem = RZA1_ADDR(port->base, reg, port->id);
|
||||
|
||||
return ioread16(mem) & BIT(bit);
|
||||
return !!(ioread16(mem) & BIT(bit));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ struct rzt2h_pinctrl {
|
|||
struct gpio_chip gpio_chip;
|
||||
struct pinctrl_gpio_range gpio_range;
|
||||
DECLARE_BITMAP(used_irqs, RZT2H_INTERRUPTS_NUM);
|
||||
spinlock_t lock; /* lock read/write registers */
|
||||
raw_spinlock_t lock; /* lock read/write registers */
|
||||
struct mutex mutex; /* serialize adding groups and functions */
|
||||
bool safety_port_enabled;
|
||||
atomic_t wakeup_path;
|
||||
|
|
@ -145,7 +145,7 @@ static void rzt2h_pinctrl_set_pfc_mode(struct rzt2h_pinctrl *pctrl,
|
|||
u64 reg64;
|
||||
u16 reg16;
|
||||
|
||||
guard(spinlock_irqsave)(&pctrl->lock);
|
||||
guard(raw_spinlock_irqsave)(&pctrl->lock);
|
||||
|
||||
/* Set pin to 'Non-use (Hi-Z input protection)' */
|
||||
reg16 = rzt2h_pinctrl_readw(pctrl, port, PM(port));
|
||||
|
|
@ -474,7 +474,7 @@ static int rzt2h_gpio_request(struct gpio_chip *chip, unsigned int offset)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
guard(spinlock_irqsave)(&pctrl->lock);
|
||||
guard(raw_spinlock_irqsave)(&pctrl->lock);
|
||||
|
||||
/* Select GPIO mode in PMC Register */
|
||||
rzt2h_pinctrl_set_gpio_en(pctrl, port, bit, true);
|
||||
|
|
@ -487,7 +487,7 @@ static void rzt2h_gpio_set_direction(struct rzt2h_pinctrl *pctrl, u32 port,
|
|||
{
|
||||
u16 reg;
|
||||
|
||||
guard(spinlock_irqsave)(&pctrl->lock);
|
||||
guard(raw_spinlock_irqsave)(&pctrl->lock);
|
||||
|
||||
reg = rzt2h_pinctrl_readw(pctrl, port, PM(port));
|
||||
reg &= ~PM_PIN_MASK(bit);
|
||||
|
|
@ -509,7 +509,7 @@ static int rzt2h_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
guard(spinlock_irqsave)(&pctrl->lock);
|
||||
guard(raw_spinlock_irqsave)(&pctrl->lock);
|
||||
|
||||
if (rzt2h_pinctrl_readb(pctrl, port, PMC(port)) & BIT(bit)) {
|
||||
/*
|
||||
|
|
@ -547,7 +547,7 @@ static int rzt2h_gpio_set(struct gpio_chip *chip, unsigned int offset,
|
|||
u8 bit = RZT2H_PIN_ID_TO_PIN(offset);
|
||||
u8 reg;
|
||||
|
||||
guard(spinlock_irqsave)(&pctrl->lock);
|
||||
guard(raw_spinlock_irqsave)(&pctrl->lock);
|
||||
|
||||
reg = rzt2h_pinctrl_readb(pctrl, port, P(port));
|
||||
if (value)
|
||||
|
|
@ -833,6 +833,7 @@ static int rzt2h_gpio_register(struct rzt2h_pinctrl *pctrl)
|
|||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Unable to parse gpio-ranges\n");
|
||||
|
||||
of_node_put(of_args.np);
|
||||
if (of_args.args[0] != 0 || of_args.args[1] != 0 ||
|
||||
of_args.args[2] != pctrl->data->n_port_pins)
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
|
|
@ -964,7 +965,7 @@ static int rzt2h_pinctrl_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
spin_lock_init(&pctrl->lock);
|
||||
raw_spin_lock_init(&pctrl->lock);
|
||||
mutex_init(&pctrl->mutex);
|
||||
platform_set_drvdata(pdev, pctrl);
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ config PINCTRL_STM32_HDP
|
|||
select PINMUX
|
||||
select GENERIC_PINCONF
|
||||
select GPIOLIB
|
||||
select GPIO_GENERIC
|
||||
help
|
||||
The Hardware Debug Port allows the observation of internal signals.
|
||||
It uses configurable multiplexer to route signals in a dedicated observation register.
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ sunxi_pinctrl_desc_find_function_by_name(struct sunxi_pinctrl *pctl,
|
|||
const char *pin_name,
|
||||
const char *func_name)
|
||||
{
|
||||
unsigned long variant = pctl->flags & SUNXI_PINCTRL_VARIANT_MASK;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pctl->desc->npins; i++) {
|
||||
|
|
@ -168,7 +169,7 @@ sunxi_pinctrl_desc_find_function_by_name(struct sunxi_pinctrl *pctl,
|
|||
while (func->name) {
|
||||
if (!strcmp(func->name, func_name) &&
|
||||
(!func->variant ||
|
||||
func->variant & pctl->variant))
|
||||
func->variant & variant))
|
||||
return func;
|
||||
|
||||
func++;
|
||||
|
|
@ -209,6 +210,8 @@ sunxi_pinctrl_desc_find_function_by_pin_and_mux(struct sunxi_pinctrl *pctl,
|
|||
const u16 pin_num,
|
||||
const u8 muxval)
|
||||
{
|
||||
unsigned long variant = pctl->flags & SUNXI_PINCTRL_VARIANT_MASK;
|
||||
|
||||
for (unsigned int i = 0; i < pctl->desc->npins; i++) {
|
||||
const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
|
||||
struct sunxi_desc_function *func = pin->functions;
|
||||
|
|
@ -216,7 +219,7 @@ sunxi_pinctrl_desc_find_function_by_pin_and_mux(struct sunxi_pinctrl *pctl,
|
|||
if (pin->pin.number != pin_num)
|
||||
continue;
|
||||
|
||||
if (pin->variant && !(pctl->variant & pin->variant))
|
||||
if (pin->variant && !(variant & pin->variant))
|
||||
continue;
|
||||
|
||||
while (func->name) {
|
||||
|
|
@ -1089,6 +1092,9 @@ static int sunxi_pinctrl_irq_request_resources(struct irq_data *d)
|
|||
{
|
||||
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
|
||||
struct sunxi_desc_function *func;
|
||||
unsigned int offset;
|
||||
u32 reg, shift, mask;
|
||||
u8 disabled_mux, muxval;
|
||||
int ret;
|
||||
|
||||
func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
|
||||
|
|
@ -1096,8 +1102,21 @@ static int sunxi_pinctrl_irq_request_resources(struct irq_data *d)
|
|||
if (!func)
|
||||
return -EINVAL;
|
||||
|
||||
ret = gpiochip_lock_as_irq(pctl->chip,
|
||||
pctl->irq_array[d->hwirq] - pctl->desc->pin_base);
|
||||
offset = pctl->irq_array[d->hwirq] - pctl->desc->pin_base;
|
||||
sunxi_mux_reg(pctl, offset, ®, &shift, &mask);
|
||||
muxval = (readl(pctl->membase + reg) & mask) >> shift;
|
||||
|
||||
/* Change muxing to GPIO INPUT mode if at reset value */
|
||||
if (pctl->flags & SUNXI_PINCTRL_NEW_REG_LAYOUT)
|
||||
disabled_mux = SUN4I_FUNC_DISABLED_NEW;
|
||||
else
|
||||
disabled_mux = SUN4I_FUNC_DISABLED_OLD;
|
||||
|
||||
if (muxval == disabled_mux)
|
||||
sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq],
|
||||
SUN4I_FUNC_INPUT);
|
||||
|
||||
ret = gpiochip_lock_as_irq(pctl->chip, offset);
|
||||
if (ret) {
|
||||
dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n",
|
||||
irqd_to_hwirq(d));
|
||||
|
|
@ -1338,6 +1357,7 @@ static int sunxi_pinctrl_add_function(struct sunxi_pinctrl *pctl,
|
|||
static int sunxi_pinctrl_build_state(struct platform_device *pdev)
|
||||
{
|
||||
struct sunxi_pinctrl *pctl = platform_get_drvdata(pdev);
|
||||
unsigned long variant = pctl->flags & SUNXI_PINCTRL_VARIANT_MASK;
|
||||
void *ptr;
|
||||
int i;
|
||||
|
||||
|
|
@ -1362,7 +1382,7 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev)
|
|||
const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
|
||||
struct sunxi_pinctrl_group *group = pctl->groups + pctl->ngroups;
|
||||
|
||||
if (pin->variant && !(pctl->variant & pin->variant))
|
||||
if (pin->variant && !(variant & pin->variant))
|
||||
continue;
|
||||
|
||||
group->name = pin->pin.name;
|
||||
|
|
@ -1387,11 +1407,11 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev)
|
|||
const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
|
||||
struct sunxi_desc_function *func;
|
||||
|
||||
if (pin->variant && !(pctl->variant & pin->variant))
|
||||
if (pin->variant && !(variant & pin->variant))
|
||||
continue;
|
||||
|
||||
for (func = pin->functions; func->name; func++) {
|
||||
if (func->variant && !(pctl->variant & func->variant))
|
||||
if (func->variant && !(variant & func->variant))
|
||||
continue;
|
||||
|
||||
/* Create interrupt mapping while we're at it */
|
||||
|
|
@ -1419,14 +1439,14 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev)
|
|||
const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
|
||||
struct sunxi_desc_function *func;
|
||||
|
||||
if (pin->variant && !(pctl->variant & pin->variant))
|
||||
if (pin->variant && !(variant & pin->variant))
|
||||
continue;
|
||||
|
||||
for (func = pin->functions; func->name; func++) {
|
||||
struct sunxi_pinctrl_function *func_item;
|
||||
const char **func_grp;
|
||||
|
||||
if (func->variant && !(pctl->variant & func->variant))
|
||||
if (func->variant && !(variant & func->variant))
|
||||
continue;
|
||||
|
||||
func_item = sunxi_pinctrl_find_function_by_name(pctl,
|
||||
|
|
@ -1568,7 +1588,7 @@ int sunxi_pinctrl_init_with_flags(struct platform_device *pdev,
|
|||
|
||||
pctl->dev = &pdev->dev;
|
||||
pctl->desc = desc;
|
||||
pctl->variant = flags & SUNXI_PINCTRL_VARIANT_MASK;
|
||||
pctl->flags = flags;
|
||||
if (flags & SUNXI_PINCTRL_NEW_REG_LAYOUT) {
|
||||
pctl->bank_mem_size = D1_BANK_MEM_SIZE;
|
||||
pctl->pull_regs_offset = D1_PULL_REGS_OFFSET;
|
||||
|
|
@ -1604,8 +1624,9 @@ int sunxi_pinctrl_init_with_flags(struct platform_device *pdev,
|
|||
|
||||
for (i = 0, pin_idx = 0; i < pctl->desc->npins; i++) {
|
||||
const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
|
||||
unsigned long variant = pctl->flags & SUNXI_PINCTRL_VARIANT_MASK;
|
||||
|
||||
if (pin->variant && !(pctl->variant & pin->variant))
|
||||
if (pin->variant && !(variant & pin->variant))
|
||||
continue;
|
||||
|
||||
pins[pin_idx++] = pin->pin;
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@
|
|||
|
||||
#define SUN4I_FUNC_INPUT 0
|
||||
#define SUN4I_FUNC_IRQ 6
|
||||
#define SUN4I_FUNC_DISABLED_OLD 7
|
||||
#define SUN4I_FUNC_DISABLED_NEW 15
|
||||
|
||||
#define SUNXI_PINCTRL_VARIANT_MASK GENMASK(7, 0)
|
||||
#define SUNXI_PINCTRL_NEW_REG_LAYOUT BIT(8)
|
||||
|
|
@ -174,7 +176,7 @@ struct sunxi_pinctrl {
|
|||
unsigned *irq_array;
|
||||
raw_spinlock_t lock;
|
||||
struct pinctrl_dev *pctl_dev;
|
||||
unsigned long variant;
|
||||
unsigned long flags;
|
||||
u32 bank_mem_size;
|
||||
u32 pull_regs_offset;
|
||||
u32 dlevel_field_width;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user