Skip to content

Commit 1bcab70

Browse files
committed
Merge tag 'intel-gpio-v5.5-1' of git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel into devel
intel-gpio for v5.5-1 * Prerequisite patch against GPIO library to register pin ranges in time. * Second attempt to fix Intel Merrifield GPIO driver to utilize irqchip. The following is an automated git shortlog grouped by driver: gpiolib: - Introduce ->add_pin_ranges() callback merrifield: - Pass irqchip when adding gpiochip - Add GPIO <-> pin mapping ranges via callback
2 parents 94fc670 + 4a5e0f9 commit 1bcab70

File tree

3 files changed

+61
-30
lines changed

3 files changed

+61
-30
lines changed

drivers/gpio/gpio-merrifield.c

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -365,8 +365,9 @@ static void mrfld_irq_handler(struct irq_desc *desc)
365365
chained_irq_exit(irqchip, desc);
366366
}
367367

368-
static void mrfld_irq_init_hw(struct mrfld_gpio *priv)
368+
static int mrfld_irq_init_hw(struct gpio_chip *chip)
369369
{
370+
struct mrfld_gpio *priv = gpiochip_get_data(chip);
370371
void __iomem *reg;
371372
unsigned int base;
372373

@@ -378,6 +379,8 @@ static void mrfld_irq_init_hw(struct mrfld_gpio *priv)
378379
reg = gpio_reg(&priv->chip, base, GFER);
379380
writel(0, reg);
380381
}
382+
383+
return 0;
381384
}
382385

383386
static const char *mrfld_gpio_get_pinctrl_dev_name(struct mrfld_gpio *priv)
@@ -396,14 +399,36 @@ static const char *mrfld_gpio_get_pinctrl_dev_name(struct mrfld_gpio *priv)
396399
return name;
397400
}
398401

399-
static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id)
402+
static int mrfld_gpio_add_pin_ranges(struct gpio_chip *chip)
400403
{
404+
struct mrfld_gpio *priv = gpiochip_get_data(chip);
401405
const struct mrfld_gpio_pinrange *range;
402406
const char *pinctrl_dev_name;
407+
unsigned int i;
408+
int retval;
409+
410+
pinctrl_dev_name = mrfld_gpio_get_pinctrl_dev_name(priv);
411+
for (i = 0; i < ARRAY_SIZE(mrfld_gpio_ranges); i++) {
412+
range = &mrfld_gpio_ranges[i];
413+
retval = gpiochip_add_pin_range(&priv->chip, pinctrl_dev_name,
414+
range->gpio_base,
415+
range->pin_base,
416+
range->npins);
417+
if (retval) {
418+
dev_err(priv->dev, "failed to add GPIO pin range\n");
419+
return retval;
420+
}
421+
}
422+
423+
return 0;
424+
}
425+
426+
static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id)
427+
{
428+
struct gpio_irq_chip *girq;
403429
struct mrfld_gpio *priv;
404430
u32 gpio_base, irq_base;
405431
void __iomem *base;
406-
unsigned int i;
407432
int retval;
408433

409434
retval = pcim_enable_device(pdev);
@@ -444,42 +469,31 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
444469
priv->chip.base = gpio_base;
445470
priv->chip.ngpio = MRFLD_NGPIO;
446471
priv->chip.can_sleep = false;
472+
priv->chip.add_pin_ranges = mrfld_gpio_add_pin_ranges;
447473

448474
raw_spin_lock_init(&priv->lock);
449475

450-
pci_set_drvdata(pdev, priv);
476+
girq = &priv->chip.irq;
477+
girq->chip = &mrfld_irqchip;
478+
girq->init_hw = mrfld_irq_init_hw;
479+
girq->parent_handler = mrfld_irq_handler;
480+
girq->num_parents = 1;
481+
girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents,
482+
sizeof(*girq->parents), GFP_KERNEL);
483+
if (!girq->parents)
484+
return -ENOMEM;
485+
girq->parents[0] = pdev->irq;
486+
girq->first = irq_base;
487+
girq->default_type = IRQ_TYPE_NONE;
488+
girq->handler = handle_bad_irq;
489+
451490
retval = devm_gpiochip_add_data(&pdev->dev, &priv->chip, priv);
452491
if (retval) {
453492
dev_err(&pdev->dev, "gpiochip_add error %d\n", retval);
454493
return retval;
455494
}
456495

457-
pinctrl_dev_name = mrfld_gpio_get_pinctrl_dev_name(priv);
458-
for (i = 0; i < ARRAY_SIZE(mrfld_gpio_ranges); i++) {
459-
range = &mrfld_gpio_ranges[i];
460-
retval = gpiochip_add_pin_range(&priv->chip,
461-
pinctrl_dev_name,
462-
range->gpio_base,
463-
range->pin_base,
464-
range->npins);
465-
if (retval) {
466-
dev_err(&pdev->dev, "failed to add GPIO pin range\n");
467-
return retval;
468-
}
469-
}
470-
471-
retval = gpiochip_irqchip_add(&priv->chip, &mrfld_irqchip, irq_base,
472-
handle_bad_irq, IRQ_TYPE_NONE);
473-
if (retval) {
474-
dev_err(&pdev->dev, "could not connect irqchip to gpiochip\n");
475-
return retval;
476-
}
477-
478-
mrfld_irq_init_hw(priv);
479-
480-
gpiochip_set_chained_irqchip(&priv->chip, &mrfld_irqchip, pdev->irq,
481-
mrfld_irq_handler);
482-
496+
pci_set_drvdata(pdev, priv);
483497
return 0;
484498
}
485499

drivers/gpio/gpiolib.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,14 @@ static void gpiochip_free_valid_mask(struct gpio_chip *gpiochip)
390390
gpiochip->valid_mask = NULL;
391391
}
392392

393+
static int gpiochip_add_pin_ranges(struct gpio_chip *gc)
394+
{
395+
if (gc->add_pin_ranges)
396+
return gc->add_pin_ranges(gc);
397+
398+
return 0;
399+
}
400+
393401
bool gpiochip_line_is_valid(const struct gpio_chip *gpiochip,
394402
unsigned int offset)
395403
{
@@ -1520,6 +1528,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
15201528
}
15211529
}
15221530

1531+
ret = gpiochip_add_pin_ranges(chip);
1532+
if (ret)
1533+
goto err_remove_of_chip;
1534+
15231535
acpi_gpiochip_add(chip);
15241536

15251537
machine_gpiochip_add(chip);

include/linux/gpio/driver.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,9 @@ struct gpio_irq_chip {
289289
* state (such as pullup/pulldown configuration).
290290
* @init_valid_mask: optional routine to initialize @valid_mask, to be used if
291291
* not all GPIOs are valid.
292+
* @add_pin_ranges: optional routine to initialize pin ranges, to be used when
293+
* requires special mapping of the pins that provides GPIO functionality.
294+
* It is called after adding GPIO chip and before adding IRQ chip.
292295
* @base: identifies the first GPIO number handled by this chip;
293296
* or, if negative during registration, requests dynamic ID allocation.
294297
* DEPRECATION: providing anything non-negative and nailing the base
@@ -379,6 +382,8 @@ struct gpio_chip {
379382
unsigned long *valid_mask,
380383
unsigned int ngpios);
381384

385+
int (*add_pin_ranges)(struct gpio_chip *chip);
386+
382387
int base;
383388
u16 ngpio;
384389
const char *const *names;

0 commit comments

Comments
 (0)