@@ -1254,6 +1254,9 @@ int gpiochip_add(struct gpio_chip *chip)
12541254}
12551255EXPORT_SYMBOL_GPL (gpiochip_add );
12561256
1257+ /* Forward-declaration */
1258+ static void gpiochip_irqchip_remove (struct gpio_chip * gpiochip );
1259+
12571260/**
12581261 * gpiochip_remove() - unregister a gpio_chip
12591262 * @chip: the chip to unregister
@@ -1270,6 +1273,7 @@ int gpiochip_remove(struct gpio_chip *chip)
12701273
12711274 spin_lock_irqsave (& gpio_lock , flags );
12721275
1276+ gpiochip_irqchip_remove (chip );
12731277 gpiochip_remove_pin_ranges (chip );
12741278 of_gpiochip_remove (chip );
12751279
@@ -1339,6 +1343,190 @@ static struct gpio_chip *find_chip_by_name(const char *name)
13391343 return gpiochip_find ((void * )name , gpiochip_match_name );
13401344}
13411345
1346+ #ifdef CONFIG_GPIOLIB_IRQCHIP
1347+
1348+ /*
1349+ * The following is irqchip helper code for gpiochips.
1350+ */
1351+
1352+ /**
1353+ * gpiochip_add_chained_irqchip() - adds a chained irqchip to a gpiochip
1354+ * @gpiochip: the gpiochip to add the irqchip to
1355+ * @irqchip: the irqchip to add to the gpiochip
1356+ * @parent_irq: the irq number corresponding to the parent IRQ for this
1357+ * chained irqchip
1358+ * @parent_handler: the parent interrupt handler for the accumulated IRQ
1359+ * coming out of the gpiochip
1360+ */
1361+ void gpiochip_set_chained_irqchip (struct gpio_chip * gpiochip ,
1362+ struct irq_chip * irqchip ,
1363+ int parent_irq ,
1364+ irq_flow_handler_t parent_handler )
1365+ {
1366+ irq_set_chained_handler (parent_irq , parent_handler );
1367+ /*
1368+ * The parent irqchip is already using the chip_data for this
1369+ * irqchip, so our callbacks simply use the handler_data.
1370+ */
1371+ irq_set_handler_data (parent_irq , gpiochip );
1372+ }
1373+ EXPORT_SYMBOL_GPL (gpiochip_set_chained_irqchip );
1374+
1375+ /**
1376+ * gpiochip_irq_map() - maps an IRQ into a GPIO irqchip
1377+ * @d: the irqdomain used by this irqchip
1378+ * @irq: the global irq number used by this GPIO irqchip irq
1379+ * @hwirq: the local IRQ/GPIO line offset on this gpiochip
1380+ *
1381+ * This function will set up the mapping for a certain IRQ line on a
1382+ * gpiochip by assigning the gpiochip as chip data, and using the irqchip
1383+ * stored inside the gpiochip.
1384+ */
1385+ static int gpiochip_irq_map (struct irq_domain * d , unsigned int irq ,
1386+ irq_hw_number_t hwirq )
1387+ {
1388+ struct gpio_chip * chip = d -> host_data ;
1389+
1390+ irq_set_chip_and_handler (irq , chip -> irqchip , chip -> irq_handler );
1391+ irq_set_chip_data (irq , chip );
1392+ #ifdef CONFIG_ARM
1393+ set_irq_flags (irq , IRQF_VALID );
1394+ #else
1395+ irq_set_noprobe (irq );
1396+ #endif
1397+ irq_set_irq_type (irq , chip -> irq_default_type );
1398+
1399+ return 0 ;
1400+ }
1401+
1402+ static const struct irq_domain_ops gpiochip_domain_ops = {
1403+ .map = gpiochip_irq_map ,
1404+ /* Virtually all GPIO irqchips are twocell:ed */
1405+ .xlate = irq_domain_xlate_twocell ,
1406+ };
1407+
1408+ static int gpiochip_irq_reqres (struct irq_data * d )
1409+ {
1410+ struct gpio_chip * chip = irq_data_get_irq_chip_data (d );
1411+
1412+ if (gpio_lock_as_irq (chip , d -> hwirq )) {
1413+ chip_err (chip ,
1414+ "unable to lock HW IRQ %lu for IRQ\n" ,
1415+ d -> hwirq );
1416+ return - EINVAL ;
1417+ }
1418+ return 0 ;
1419+ }
1420+
1421+ static void gpiochip_irq_relres (struct irq_data * d )
1422+ {
1423+ struct gpio_chip * chip = irq_data_get_irq_chip_data (d );
1424+
1425+ gpio_unlock_as_irq (chip , d -> hwirq );
1426+ }
1427+
1428+ static int gpiochip_to_irq (struct gpio_chip * chip , unsigned offset )
1429+ {
1430+ return irq_find_mapping (chip -> irqdomain , offset );
1431+ }
1432+
1433+ /**
1434+ * gpiochip_irqchip_remove() - removes an irqchip added to a gpiochip
1435+ * @gpiochip: the gpiochip to remove the irqchip from
1436+ *
1437+ * This is called only from gpiochip_remove()
1438+ */
1439+ static void gpiochip_irqchip_remove (struct gpio_chip * gpiochip )
1440+ {
1441+ if (gpiochip -> irqdomain )
1442+ irq_domain_remove (gpiochip -> irqdomain );
1443+
1444+ if (gpiochip -> irqchip ) {
1445+ gpiochip -> irqchip -> irq_request_resources = NULL ;
1446+ gpiochip -> irqchip -> irq_release_resources = NULL ;
1447+ gpiochip -> irqchip = NULL ;
1448+ }
1449+ }
1450+
1451+ /**
1452+ * gpiochip_irqchip_add() - adds an irqchip to a gpiochip
1453+ * @gpiochip: the gpiochip to add the irqchip to
1454+ * @irqchip: the irqchip to add to the gpiochip
1455+ * @first_irq: if not dynamically assigned, the base (first) IRQ to
1456+ * allocate gpiochip irqs from
1457+ * @handler: the irq handler to use (often a predefined irq core function)
1458+ * @type: the default type for IRQs on this irqchip
1459+ *
1460+ * This function closely associates a certain irqchip with a certain
1461+ * gpiochip, providing an irq domain to translate the local IRQs to
1462+ * global irqs in the gpiolib core, and making sure that the gpiochip
1463+ * is passed as chip data to all related functions. Driver callbacks
1464+ * need to use container_of() to get their local state containers back
1465+ * from the gpiochip passed as chip data. An irqdomain will be stored
1466+ * in the gpiochip that shall be used by the driver to handle IRQ number
1467+ * translation. The gpiochip will need to be initialized and registered
1468+ * before calling this function.
1469+ *
1470+ * This function will handle two cell:ed simple IRQs. Everything else
1471+ * need to be open coded.
1472+ */
1473+ int gpiochip_irqchip_add (struct gpio_chip * gpiochip ,
1474+ struct irq_chip * irqchip ,
1475+ unsigned int first_irq ,
1476+ irq_flow_handler_t handler ,
1477+ unsigned int type )
1478+ {
1479+ struct device_node * of_node ;
1480+ unsigned int offset ;
1481+
1482+ if (!gpiochip || !irqchip )
1483+ return - EINVAL ;
1484+
1485+ if (!gpiochip -> dev ) {
1486+ pr_err ("missing gpiochip .dev parent pointer\n" );
1487+ return - EINVAL ;
1488+ }
1489+ of_node = gpiochip -> dev -> of_node ;
1490+ #ifdef CONFIG_OF_GPIO
1491+ /*
1492+ * If the gpiochip has an assigned OF node this takes precendence
1493+ * FIXME: get rid of this and use gpiochip->dev->of_node everywhere
1494+ */
1495+ if (gpiochip -> of_node )
1496+ of_node = gpiochip -> of_node ;
1497+ #endif
1498+ gpiochip -> irqchip = irqchip ;
1499+ gpiochip -> irq_handler = handler ;
1500+ gpiochip -> irq_default_type = type ;
1501+ gpiochip -> to_irq = gpiochip_to_irq ;
1502+ gpiochip -> irqdomain = irq_domain_add_simple (of_node ,
1503+ gpiochip -> ngpio , first_irq ,
1504+ & gpiochip_domain_ops , gpiochip );
1505+ if (!gpiochip -> irqdomain ) {
1506+ gpiochip -> irqchip = NULL ;
1507+ return - EINVAL ;
1508+ }
1509+ irqchip -> irq_request_resources = gpiochip_irq_reqres ;
1510+ irqchip -> irq_release_resources = gpiochip_irq_relres ;
1511+
1512+ /*
1513+ * Prepare the mapping since the irqchip shall be orthogonal to
1514+ * any gpiochip calls. If the first_irq was zero, this is
1515+ * necessary to allocate descriptors for all IRQs.
1516+ */
1517+ for (offset = 0 ; offset < gpiochip -> ngpio ; offset ++ )
1518+ irq_create_mapping (gpiochip -> irqdomain , offset );
1519+
1520+ return 0 ;
1521+ }
1522+ EXPORT_SYMBOL_GPL (gpiochip_irqchip_add );
1523+
1524+ #else /* CONFIG_GPIOLIB_IRQCHIP */
1525+
1526+ static void gpiochip_irqchip_remove (struct gpio_chip * gpiochip ) {}
1527+
1528+ #endif /* CONFIG_GPIOLIB_IRQCHIP */
1529+
13421530#ifdef CONFIG_PINCTRL
13431531
13441532/**
0 commit comments