hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/gpio/gpio-thunderx.c
....@@ -15,6 +15,7 @@
1515 #include <linux/module.h>
1616 #include <linux/pci.h>
1717 #include <linux/spinlock.h>
18
+#include <asm-generic/msi.h>
1819
1920
2021 #define GPIO_RX_DAT 0x0
....@@ -53,7 +54,6 @@
5354 struct thunderx_gpio {
5455 struct gpio_chip chip;
5556 u8 __iomem *register_base;
56
- struct irq_domain *irqd;
5757 struct msix_entry *msix_entries; /* per line MSI-X */
5858 struct thunderx_line *line_entries; /* per line irq info */
5959 raw_spinlock_t lock;
....@@ -170,7 +170,10 @@
170170
171171 bit_cfg = readq(txgpio->register_base + bit_cfg_reg(line));
172172
173
- return !(bit_cfg & GPIO_BIT_CFG_TX_OE);
173
+ if (bit_cfg & GPIO_BIT_CFG_TX_OE)
174
+ return GPIO_LINE_DIRECTION_OUT;
175
+
176
+ return GPIO_LINE_DIRECTION_IN;
174177 }
175178
176179 static int thunderx_gpio_set_config(struct gpio_chip *chip,
....@@ -283,54 +286,60 @@
283286 }
284287 }
285288
286
-static void thunderx_gpio_irq_ack(struct irq_data *data)
289
+static void thunderx_gpio_irq_ack(struct irq_data *d)
287290 {
288
- struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
291
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
292
+ struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
289293
290294 writeq(GPIO_INTR_INTR,
291
- txline->txgpio->register_base + intr_reg(txline->line));
295
+ txgpio->register_base + intr_reg(irqd_to_hwirq(d)));
292296 }
293297
294
-static void thunderx_gpio_irq_mask(struct irq_data *data)
298
+static void thunderx_gpio_irq_mask(struct irq_data *d)
295299 {
296
- struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
300
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
301
+ struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
297302
298303 writeq(GPIO_INTR_ENA_W1C,
299
- txline->txgpio->register_base + intr_reg(txline->line));
304
+ txgpio->register_base + intr_reg(irqd_to_hwirq(d)));
300305 }
301306
302
-static void thunderx_gpio_irq_mask_ack(struct irq_data *data)
307
+static void thunderx_gpio_irq_mask_ack(struct irq_data *d)
303308 {
304
- struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
309
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
310
+ struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
305311
306312 writeq(GPIO_INTR_ENA_W1C | GPIO_INTR_INTR,
307
- txline->txgpio->register_base + intr_reg(txline->line));
313
+ txgpio->register_base + intr_reg(irqd_to_hwirq(d)));
308314 }
309315
310
-static void thunderx_gpio_irq_unmask(struct irq_data *data)
316
+static void thunderx_gpio_irq_unmask(struct irq_data *d)
311317 {
312
- struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
318
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
319
+ struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
313320
314321 writeq(GPIO_INTR_ENA_W1S,
315
- txline->txgpio->register_base + intr_reg(txline->line));
322
+ txgpio->register_base + intr_reg(irqd_to_hwirq(d)));
316323 }
317324
318
-static int thunderx_gpio_irq_set_type(struct irq_data *data,
325
+static int thunderx_gpio_irq_set_type(struct irq_data *d,
319326 unsigned int flow_type)
320327 {
321
- struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
322
- struct thunderx_gpio *txgpio = txline->txgpio;
328
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
329
+ struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
330
+ struct thunderx_line *txline =
331
+ &txgpio->line_entries[irqd_to_hwirq(d)];
323332 u64 bit_cfg;
324333
325
- irqd_set_trigger_type(data, flow_type);
334
+ irqd_set_trigger_type(d, flow_type);
326335
327336 bit_cfg = txline->fil_bits | GPIO_BIT_CFG_INT_EN;
328337
329338 if (flow_type & IRQ_TYPE_EDGE_BOTH) {
330
- irq_set_handler_locked(data, handle_fasteoi_ack_irq);
339
+ irq_set_handler_locked(d, handle_fasteoi_ack_irq);
331340 bit_cfg |= GPIO_BIT_CFG_INT_TYPE;
332341 } else {
333
- irq_set_handler_locked(data, handle_fasteoi_mask_irq);
342
+ irq_set_handler_locked(d, handle_fasteoi_mask_irq);
334343 }
335344
336345 raw_spin_lock(&txgpio->lock);
....@@ -359,41 +368,6 @@
359368 irq_chip_disable_parent(data);
360369 }
361370
362
-static int thunderx_gpio_irq_request_resources(struct irq_data *data)
363
-{
364
- struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
365
- struct thunderx_gpio *txgpio = txline->txgpio;
366
- struct irq_data *parent_data = data->parent_data;
367
- int r;
368
-
369
- r = gpiochip_lock_as_irq(&txgpio->chip, txline->line);
370
- if (r)
371
- return r;
372
-
373
- if (parent_data && parent_data->chip->irq_request_resources) {
374
- r = parent_data->chip->irq_request_resources(parent_data);
375
- if (r)
376
- goto error;
377
- }
378
-
379
- return 0;
380
-error:
381
- gpiochip_unlock_as_irq(&txgpio->chip, txline->line);
382
- return r;
383
-}
384
-
385
-static void thunderx_gpio_irq_release_resources(struct irq_data *data)
386
-{
387
- struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
388
- struct thunderx_gpio *txgpio = txline->txgpio;
389
- struct irq_data *parent_data = data->parent_data;
390
-
391
- if (parent_data && parent_data->chip->irq_release_resources)
392
- parent_data->chip->irq_release_resources(parent_data);
393
-
394
- gpiochip_unlock_as_irq(&txgpio->chip, txline->line);
395
-}
396
-
397371 /*
398372 * Interrupts are chained from underlying MSI-X vectors. We have
399373 * these irq_chip functions to be able to handle level triggering
....@@ -410,48 +384,42 @@
410384 .irq_unmask = thunderx_gpio_irq_unmask,
411385 .irq_eoi = irq_chip_eoi_parent,
412386 .irq_set_affinity = irq_chip_set_affinity_parent,
413
- .irq_request_resources = thunderx_gpio_irq_request_resources,
414
- .irq_release_resources = thunderx_gpio_irq_release_resources,
415387 .irq_set_type = thunderx_gpio_irq_set_type,
416388
417389 .flags = IRQCHIP_SET_TYPE_MASKED
418390 };
419391
420
-static int thunderx_gpio_irq_translate(struct irq_domain *d,
421
- struct irq_fwspec *fwspec,
422
- irq_hw_number_t *hwirq,
423
- unsigned int *type)
392
+static int thunderx_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
393
+ unsigned int child,
394
+ unsigned int child_type,
395
+ unsigned int *parent,
396
+ unsigned int *parent_type)
424397 {
425
- struct thunderx_gpio *txgpio = d->host_data;
398
+ struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
399
+ struct irq_data *irqd;
400
+ unsigned int irq;
426401
427
- if (WARN_ON(fwspec->param_count < 2))
402
+ irq = txgpio->msix_entries[child].vector;
403
+ irqd = irq_domain_get_irq_data(gc->irq.parent_domain, irq);
404
+ if (!irqd)
428405 return -EINVAL;
429
- if (fwspec->param[0] >= txgpio->chip.ngpio)
430
- return -EINVAL;
431
- *hwirq = fwspec->param[0];
432
- *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
406
+ *parent = irqd_to_hwirq(irqd);
407
+ *parent_type = IRQ_TYPE_LEVEL_HIGH;
433408 return 0;
434409 }
435410
436
-static int thunderx_gpio_irq_alloc(struct irq_domain *d, unsigned int virq,
437
- unsigned int nr_irqs, void *arg)
411
+static void *thunderx_gpio_populate_parent_alloc_info(struct gpio_chip *chip,
412
+ unsigned int parent_hwirq,
413
+ unsigned int parent_type)
438414 {
439
- struct thunderx_line *txline = arg;
415
+ msi_alloc_info_t *info;
440416
441
- return irq_domain_set_hwirq_and_chip(d, virq, txline->line,
442
- &thunderx_gpio_irq_chip, txline);
443
-}
417
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
418
+ if (!info)
419
+ return NULL;
444420
445
-static const struct irq_domain_ops thunderx_gpio_irqd_ops = {
446
- .alloc = thunderx_gpio_irq_alloc,
447
- .translate = thunderx_gpio_irq_translate
448
-};
449
-
450
-static int thunderx_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
451
-{
452
- struct thunderx_gpio *txgpio = gpiochip_get_data(chip);
453
-
454
- return irq_find_mapping(txgpio->irqd, offset);
421
+ info->hwirq = parent_hwirq;
422
+ return info;
455423 }
456424
457425 static int thunderx_gpio_probe(struct pci_dev *pdev,
....@@ -461,6 +429,7 @@
461429 struct device *dev = &pdev->dev;
462430 struct thunderx_gpio *txgpio;
463431 struct gpio_chip *chip;
432
+ struct gpio_irq_chip *girq;
464433 int ngpio, i;
465434 int err = 0;
466435
....@@ -505,8 +474,8 @@
505474 }
506475
507476 txgpio->msix_entries = devm_kcalloc(dev,
508
- ngpio, sizeof(struct msix_entry),
509
- GFP_KERNEL);
477
+ ngpio, sizeof(struct msix_entry),
478
+ GFP_KERNEL);
510479 if (!txgpio->msix_entries) {
511480 err = -ENOMEM;
512481 goto out;
....@@ -547,27 +516,6 @@
547516 if (err < 0)
548517 goto out;
549518
550
- /*
551
- * Push GPIO specific irqdomain on hierarchy created as a side
552
- * effect of the pci_enable_msix()
553
- */
554
- txgpio->irqd = irq_domain_create_hierarchy(irq_get_irq_data(txgpio->msix_entries[0].vector)->domain,
555
- 0, 0, of_node_to_fwnode(dev->of_node),
556
- &thunderx_gpio_irqd_ops, txgpio);
557
- if (!txgpio->irqd) {
558
- err = -ENOMEM;
559
- goto out;
560
- }
561
-
562
- /* Push on irq_data and the domain for each line. */
563
- for (i = 0; i < ngpio; i++) {
564
- err = irq_domain_push_irq(txgpio->irqd,
565
- txgpio->msix_entries[i].vector,
566
- &txgpio->line_entries[i]);
567
- if (err < 0)
568
- dev_err(dev, "irq_domain_push_irq: %d\n", err);
569
- }
570
-
571519 chip->label = KBUILD_MODNAME;
572520 chip->parent = dev;
573521 chip->owner = THIS_MODULE;
....@@ -582,10 +530,34 @@
582530 chip->set = thunderx_gpio_set;
583531 chip->set_multiple = thunderx_gpio_set_multiple;
584532 chip->set_config = thunderx_gpio_set_config;
585
- chip->to_irq = thunderx_gpio_to_irq;
533
+ girq = &chip->irq;
534
+ girq->chip = &thunderx_gpio_irq_chip;
535
+ girq->fwnode = of_node_to_fwnode(dev->of_node);
536
+ girq->parent_domain =
537
+ irq_get_irq_data(txgpio->msix_entries[0].vector)->domain;
538
+ girq->child_to_parent_hwirq = thunderx_gpio_child_to_parent_hwirq;
539
+ girq->populate_parent_alloc_arg = thunderx_gpio_populate_parent_alloc_info;
540
+ girq->handler = handle_bad_irq;
541
+ girq->default_type = IRQ_TYPE_NONE;
542
+
586543 err = devm_gpiochip_add_data(dev, chip, txgpio);
587544 if (err)
588545 goto out;
546
+
547
+ /* Push on irq_data and the domain for each line. */
548
+ for (i = 0; i < ngpio; i++) {
549
+ struct irq_fwspec fwspec;
550
+
551
+ fwspec.fwnode = of_node_to_fwnode(dev->of_node);
552
+ fwspec.param_count = 2;
553
+ fwspec.param[0] = i;
554
+ fwspec.param[1] = IRQ_TYPE_NONE;
555
+ err = irq_domain_push_irq(girq->domain,
556
+ txgpio->msix_entries[i].vector,
557
+ &fwspec);
558
+ if (err < 0)
559
+ dev_err(dev, "irq_domain_push_irq: %d\n", err);
560
+ }
589561
590562 dev_info(dev, "ThunderX GPIO: %d lines with base %d.\n",
591563 ngpio, chip->base);
....@@ -601,10 +573,10 @@
601573 struct thunderx_gpio *txgpio = pci_get_drvdata(pdev);
602574
603575 for (i = 0; i < txgpio->chip.ngpio; i++)
604
- irq_domain_pop_irq(txgpio->irqd,
576
+ irq_domain_pop_irq(txgpio->chip.irq.domain,
605577 txgpio->msix_entries[i].vector);
606578
607
- irq_domain_remove(txgpio->irqd);
579
+ irq_domain_remove(txgpio->chip.irq.domain);
608580
609581 pci_set_drvdata(pdev, NULL);
610582 }