Commit 3e5832e9 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pinctrl-v5.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pin control fixes from Linus Walleij:
 "Most interesting and urgent is the Intel stuff affecting Chromebooks
  and laptops.

   - Fix up group name building on the Intel Thunderbay

   - Fix interrupt problems on the Intel Cherryview

   - Fix some pin data on the Sunxi H616

   - Fix up the CONFIG_PINCTRL_ST Kconfig sort order as noted during the
     merge window

   - Fix an unexpected interrupt problem on the Intel Sunrisepoint

   - Fix a glitch when updating IRQ flags on all Intel pin controllers

   - Revert a Zynqmp patch to unify the pin naming, let's find some
     better solution

   - Fix some error paths in the Broadcom BCM2835 driver

   - Fix a Kconfig problem pertaining to the BCM63XX drivers

   - Fix the regmap support in the Microchip SGPIO driver"

* tag 'pinctrl-v5.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
  pinctrl: microchip-sgpio: Fix support for regmap
  pinctrl: bcm63xx: fix unmet dependency on REGMAP for GPIO_REGMAP
  pinctrl: bcm2835: Fix a few error paths
  pinctrl: zynqmp: Revert "Unify pin naming"
  pinctrl: intel: Fix a glitch when updating IRQ flags on a preconfigured line
  pinctrl: intel: fix unexpected interrupt
  pinctrl: Place correctly CONFIG_PINCTRL_ST in the Makefile
  pinctrl: sunxi: Fix H616 I2S3 pin data
  pinctrl: cherryview: Trigger hwirq0 for interrupt-lines without a mapping
  pinctrl: thunderbay: rework loops looking for groups names
  pinctrl: thunderbay: comment process of building functions a bit
parents 9f7fb8de baf927a8
......@@ -42,9 +42,9 @@ obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
obj-$(CONFIG_PINCTRL_STARFIVE) += pinctrl-starfive.o
obj-$(CONFIG_PINCTRL_STMFX) += pinctrl-stmfx.o
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
obj-$(CONFIG_PINCTRL_SX150X) += pinctrl-sx150x.o
obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o
obj-$(CONFIG_PINCTRL_THUNDERBAY) += pinctrl-thunderbay.o
......
......@@ -35,6 +35,7 @@ config PINCTRL_BCM63XX
select PINCONF
select GENERIC_PINCONF
select GPIOLIB
select REGMAP
select GPIO_REGMAP
config PINCTRL_BCM6318
......
......@@ -1269,16 +1269,18 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents) {
pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
return -ENOMEM;
err = -ENOMEM;
goto out_remove;
}
if (is_7211) {
pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS,
sizeof(*pc->wake_irq),
GFP_KERNEL);
if (!pc->wake_irq)
return -ENOMEM;
if (!pc->wake_irq) {
err = -ENOMEM;
goto out_remove;
}
}
/*
......@@ -1306,8 +1308,10 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
len = strlen(dev_name(pc->dev)) + 16;
name = devm_kzalloc(pc->dev, len, GFP_KERNEL);
if (!name)
return -ENOMEM;
if (!name) {
err = -ENOMEM;
goto out_remove;
}
snprintf(name, len, "%s:bank%d", dev_name(pc->dev), i);
......@@ -1326,11 +1330,14 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
err = gpiochip_add_data(&pc->gpio_chip, pc);
if (err) {
dev_err(dev, "could not add GPIO chip\n");
pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
return err;
goto out_remove;
}
return 0;
out_remove:
pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
return err;
}
static struct platform_driver bcm2835_pinctrl_driver = {
......
......@@ -1471,8 +1471,9 @@ static void chv_gpio_irq_handler(struct irq_desc *desc)
offset = cctx->intr_lines[intr_line];
if (offset == CHV_INVALID_HWIRQ) {
dev_err(dev, "interrupt on unused interrupt line %u\n", intr_line);
continue;
dev_warn_once(dev, "interrupt on unmapped interrupt line %u\n", intr_line);
/* Some boards expect hwirq 0 to trigger in this case */
offset = 0;
}
generic_handle_domain_irq(gc->irq.domain, offset);
......
......@@ -451,8 +451,8 @@ static void intel_gpio_set_gpio_mode(void __iomem *padcfg0)
value &= ~PADCFG0_PMODE_MASK;
value |= PADCFG0_PMODE_GPIO;
/* Disable input and output buffers */
value |= PADCFG0_GPIORXDIS;
/* Disable TX buffer and enable RX (this will be input) */
value &= ~PADCFG0_GPIORXDIS;
value |= PADCFG0_GPIOTXDIS;
/* Disable SCI/SMI/NMI generation */
......@@ -497,9 +497,6 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
intel_gpio_set_gpio_mode(padcfg0);
/* Disable TX buffer and enable RX (this will be input) */
__intel_gpio_set_direction(padcfg0, true);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
return 0;
......@@ -1115,9 +1112,6 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned int type)
intel_gpio_set_gpio_mode(reg);
/* Disable TX buffer and enable RX (this will be input) */
__intel_gpio_set_direction(reg, true);
value = readl(reg);
value &= ~(PADCFG0_RXEVCFG_MASK | PADCFG0_RXINV);
......@@ -1216,6 +1210,39 @@ static irqreturn_t intel_gpio_irq(int irq, void *data)
return IRQ_RETVAL(ret);
}
static void intel_gpio_irq_init(struct intel_pinctrl *pctrl)
{
int i;
for (i = 0; i < pctrl->ncommunities; i++) {
const struct intel_community *community;
void __iomem *base;
unsigned int gpp;
community = &pctrl->communities[i];
base = community->regs;
for (gpp = 0; gpp < community->ngpps; gpp++) {
/* Mask and clear all interrupts */
writel(0, base + community->ie_offset + gpp * 4);
writel(0xffff, base + community->is_offset + gpp * 4);
}
}
}
static int intel_gpio_irq_init_hw(struct gpio_chip *gc)
{
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
/*
* Make sure the interrupt lines are in a proper state before
* further configuration.
*/
intel_gpio_irq_init(pctrl);
return 0;
}
static int intel_gpio_add_community_ranges(struct intel_pinctrl *pctrl,
const struct intel_community *community)
{
......@@ -1320,6 +1347,7 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
girq->num_parents = 0;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_bad_irq;
girq->init_hw = intel_gpio_irq_init_hw;
ret = devm_gpiochip_add_data(pctrl->dev, &pctrl->chip, pctrl);
if (ret) {
......@@ -1695,26 +1723,6 @@ int intel_pinctrl_suspend_noirq(struct device *dev)
}
EXPORT_SYMBOL_GPL(intel_pinctrl_suspend_noirq);
static void intel_gpio_irq_init(struct intel_pinctrl *pctrl)
{
size_t i;
for (i = 0; i < pctrl->ncommunities; i++) {
const struct intel_community *community;
void __iomem *base;
unsigned int gpp;
community = &pctrl->communities[i];
base = community->regs;
for (gpp = 0; gpp < community->ngpps; gpp++) {
/* Mask and clear all interrupts */
writel(0, base + community->ie_offset + gpp * 4);
writel(0xffff, base + community->is_offset + gpp * 4);
}
}
}
static bool intel_gpio_update_reg(void __iomem *reg, u32 mask, u32 value)
{
u32 curr, updated;
......
......@@ -137,7 +137,8 @@ static inline int sgpio_addr_to_pin(struct sgpio_priv *priv, int port, int bit)
static inline u32 sgpio_get_addr(struct sgpio_priv *priv, u32 rno, u32 off)
{
return priv->properties->regoff[rno] + off;
return (priv->properties->regoff[rno] + off) *
regmap_get_reg_stride(priv->regs);
}
static u32 sgpio_readl(struct sgpio_priv *priv, u32 rno, u32 off)
......
......@@ -773,63 +773,42 @@ static int thunderbay_build_groups(struct thunderbay_pinctrl *tpc)
static int thunderbay_add_functions(struct thunderbay_pinctrl *tpc, struct function_desc *funcs)
{
struct function_desc *function = funcs;
int i;
/* Assign the groups for each function */
for (i = 0; i < tpc->soc->npins; i++) {
const struct pinctrl_pin_desc *pin_info = thunderbay_pins + i;
struct thunderbay_mux_desc *pin_mux = pin_info->drv_data;
while (pin_mux->name) {
const char **grp;
int j, grp_num, match = 0;
size_t grp_size;
struct function_desc *func;
for (j = 0; j < tpc->nfuncs; j++) {
if (!strcmp(pin_mux->name, function[j].name)) {
match = 1;
break;
}
}
for (i = 0; i < tpc->nfuncs; i++) {
struct function_desc *func = &funcs[i];
const char **group_names;
unsigned int grp_idx = 0;
int j;
group_names = devm_kcalloc(tpc->dev, func->num_group_names,
sizeof(*group_names), GFP_KERNEL);
if (!group_names)
return -ENOMEM;
if (!match)
return -EINVAL;
for (j = 0; j < tpc->soc->npins; j++) {
const struct pinctrl_pin_desc *pin_info = &thunderbay_pins[j];
struct thunderbay_mux_desc *pin_mux;
func = function + j;
grp_num = func->num_group_names;
grp_size = sizeof(*func->group_names);
if (!func->group_names) {
func->group_names = devm_kcalloc(tpc->dev,
grp_num,
grp_size,
GFP_KERNEL);
if (!func->group_names) {
kfree(func);
return -ENOMEM;
for (pin_mux = pin_info->drv_data; pin_mux->name; pin_mux++) {
if (!strcmp(pin_mux->name, func->name))
group_names[grp_idx++] = pin_info->name;
}
}
grp = func->group_names;
while (*grp)
grp++;
*grp = pin_info->name;
pin_mux++;
}
func->group_names = group_names;
}
/* Add all functions */
for (i = 0; i < tpc->nfuncs; i++) {
pinmux_generic_add_function(tpc->pctrl,
function[i].name,
function[i].group_names,
function[i].num_group_names,
function[i].data);
funcs[i].name,
funcs[i].group_names,
funcs[i].num_group_names,
funcs[i].data);
}
kfree(function);
kfree(funcs);
return 0;
}
......@@ -839,27 +818,30 @@ static int thunderbay_build_functions(struct thunderbay_pinctrl *tpc)
void *ptr;
int pin;
/* Total number of functions is unknown at this point. Allocate first. */
/*
* Allocate maximum possible number of functions. Assume every pin
* being part of 8 (hw maximum) globally unique muxes.
*/
tpc->nfuncs = 0;
thunderbay_funcs = kcalloc(tpc->soc->npins * 8,
sizeof(*thunderbay_funcs), GFP_KERNEL);
if (!thunderbay_funcs)
return -ENOMEM;
/* Find total number of functions and each's properties */
/* Setup 1 function for each unique mux */
for (pin = 0; pin < tpc->soc->npins; pin++) {
const struct pinctrl_pin_desc *pin_info = thunderbay_pins + pin;
struct thunderbay_mux_desc *pin_mux = pin_info->drv_data;
struct thunderbay_mux_desc *pin_mux;
while (pin_mux->name) {
struct function_desc *func = thunderbay_funcs;
for (pin_mux = pin_info->drv_data; pin_mux->name; pin_mux++) {
struct function_desc *func;
while (func->name) {
/* Check if we already have function for this mux */
for (func = thunderbay_funcs; func->name; func++) {
if (!strcmp(pin_mux->name, func->name)) {
func->num_group_names++;
break;
}
func++;
}
if (!func->name) {
......@@ -868,8 +850,6 @@ static int thunderbay_build_functions(struct thunderbay_pinctrl *tpc)
func->data = (int *)&pin_mux->mode;
tpc->nfuncs++;
}
pin_mux++;
}
}
......
......@@ -809,7 +809,6 @@ static int zynqmp_pinctrl_prepare_pin_desc(struct device *dev,
unsigned int *npins)
{
struct pinctrl_pin_desc *pins, *pin;
char **pin_names;
int ret;
int i;
......@@ -821,14 +820,13 @@ static int zynqmp_pinctrl_prepare_pin_desc(struct device *dev,
if (!pins)
return -ENOMEM;
pin_names = devm_kasprintf_strarray(dev, ZYNQMP_PIN_PREFIX, *npins);
if (IS_ERR(pin_names))
return PTR_ERR(pin_names);
for (i = 0; i < *npins; i++) {
pin = &pins[i];
pin->number = i;
pin->name = pin_names[i];
pin->name = devm_kasprintf(dev, GFP_KERNEL, "%s%d",
ZYNQMP_PIN_PREFIX, i);
if (!pin->name)
return -ENOMEM;
}
*zynqmp_pins = pins;
......
......@@ -363,16 +363,16 @@ static const struct sunxi_desc_pin h616_pins[] = {
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "uart2"), /* CTS */
SUNXI_FUNCTION(0x3, "i2s3"), /* DO0 */
SUNXI_FUNCTION(0x3, "i2s3_dout0"), /* DO0 */
SUNXI_FUNCTION(0x4, "spi1"), /* MISO */
SUNXI_FUNCTION(0x5, "i2s3"), /* DI1 */
SUNXI_FUNCTION(0x5, "i2s3_din1"), /* DI1 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 8)), /* PH_EINT8 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x3, "i2s3"), /* DI0 */
SUNXI_FUNCTION(0x3, "i2s3_din0"), /* DI0 */
SUNXI_FUNCTION(0x4, "spi1"), /* CS1 */
SUNXI_FUNCTION(0x3, "i2s3"), /* DO1 */
SUNXI_FUNCTION(0x5, "i2s3_dout1"), /* DO1 */
SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 9)), /* PH_EINT9 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
......
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