[PATCH linux dev-4.10] drivers/leds: Add GPIO keys for PCA955x and ast24/2500 gpio

Christopher Bostic cbostic at linux.vnet.ibm.com
Sat Jul 1 08:55:21 AEST 2017


Define gpio keys for power supply presence, ucd alert, and fan presence.

Link pca955x to parent i2c interrupt controller so that new pca955x gpio
keys for fan presence haning off of pca955x can be defined.

Signed-off-by: Christopher Bostic <cbostic at linux.vnet.ibm.com>
---
 arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts | 77 ++++++++++++++++++++++++
 drivers/leds/leds-pca955x.c                      | 64 ++++++++++++++++++++
 2 files changed, 141 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts b/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts
index 31315d0..24ea9944 100644
--- a/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts
@@ -46,6 +46,48 @@
 			gpios = <&gpio ASPEED_GPIO(J, 2) GPIO_ACTIVE_LOW>;
 			linux,code = <ASPEED_GPIO(J, 2)>;
 		};
+
+		ps0-presence {
+			label = "ps0-presence";
+			gpios = <&gpio ASPEED_GPIO(P, 7) GPIO_ACTIVE_LOW>;
+			linux,code = <ASPEED_GPIO(P, 7)>;
+		};
+
+		ps1-presence {
+			label = "ps1-presence";
+			gpios = <&gpio ASPEED_GPIO(N, 0) GPIO_ACTIVE_LOW>;
+			linux,code = <ASPEED_GPIO(N, 0)>;
+		};
+
+		ucd-alert {
+			label = "ucd-alert";
+			gpios = <&gpio ASPEED_GPIO(I, 2) GPIO_ACTIVE_LOW>;
+			linux,code = <ASPEED_GPIO(I, 2)>;
+		};
+
+		fan0-presence {
+			label = "fan0-presence";
+			gpios = <&pca0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <0>;
+		};
+
+		fan1-presence {
+			label = "fan1-presence";
+			gpios = <&pca0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <1>;
+		};
+
+		fan2-presence {
+			label = "fan2-presence";
+			gpios = <&pca0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <2>;
+		};
+
+		fan3-presence {
+			label = "fan3-presence";
+			gpios = <&pca0 3 GPIO_ACTIVE_LOW>;
+			linux,code = <3>;
+		};
 	};
 
 	leds {
@@ -203,6 +245,41 @@
 		compatible = "infineon,dps310";
 		reg = <0x76>;
 	};
+
+	pca0: pca9552 at 60 {
+		compatible = "nxp,pca9552";
+		reg = <0x60>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-parent = <&i2c_ic>;
+		interrupts = <3>;
+
+		gpio-line-names = "FAN0_PRESENSE_N", "FAN1_PRESENSE_N",
+				"FAN2_PRESENSE_N", "FAN3_PRESENSE_N";
+
+		gpio at 4 {
+			reg = <4>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+
+		gpio at 5 {
+			reg = <5>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+
+		gpio at 6 {
+			reg = <6>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+
+		gpio at 7 {
+			reg = <7>;
+			type = <PCA955X_TYPE_GPIO>;
+		};
+	};
 };
 
 &i2c4 {
diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c
index 9216742..88990f1 100644
--- a/drivers/leds/leds-pca955x.c
+++ b/drivers/leds/leds-pca955x.c
@@ -52,6 +52,7 @@
 #include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/interrupt.h>
 
 #include <dt-bindings/leds/leds-pca955x.h>
 
@@ -389,6 +390,66 @@ static int pca955x_gpio_direction_output(struct gpio_chip *gc,
 }
 #endif
 
+static void pca955x_irq_mask(struct irq_data *d)
+{
+}
+
+static void pca955x_irq_unmask(struct irq_data *d)
+{
+}
+
+static void pca955x_irq_bus_lock(struct irq_data *d)
+{
+}
+
+static void pca955x_irq_bus_sync_unlock(struct irq_data *d)
+{
+}
+
+static int pca955x_irq_set_type(struct irq_data *d, unsigned int type)
+{
+	return 0;
+}
+
+static struct irq_chip pca955x_irq_chip = {
+	.name			= "pca955x",
+	.irq_mask		= pca955x_irq_mask,
+	.irq_unmask		= pca955x_irq_unmask,
+	.irq_bus_lock		= pca955x_irq_bus_lock,
+	.irq_bus_sync_unlock	= pca955x_irq_bus_sync_unlock,
+	.irq_set_type		= pca955x_irq_set_type,
+};
+
+static int pca955x_irq_setup(struct pca955x *chip, int irq_base)
+{
+	struct i2c_client *client;
+	int ret;
+
+	if (!chip)
+		return 0;
+
+	client = chip->client;
+	if (!client)
+		return 0;
+
+	if (client->irq && irq_base >= 0) {
+		ret = gpiochip_irqchip_add_nested(&chip->gpio,
+						&pca955x_irq_chip,
+						irq_base,
+						handle_simple_irq,
+						IRQ_TYPE_NONE);
+		if (ret) {
+			dev_err(&client->dev,
+				"could not connect irqchip to gpiochip\n");
+			return ret;
+		}
+		gpiochip_set_nested_irqchip(&chip->gpio,
+					&pca955x_irq_chip,
+					client->irq);
+	}
+	return 0;
+}
+
 static int pca955x_probe(struct i2c_client *client,
 					const struct i2c_device_id *id)
 {
@@ -543,6 +604,9 @@ static int pca955x_probe(struct i2c_client *client,
 		}
 	}
 #endif
+	err = pca955x_irq_setup(pca955x, 0);
+	if (err)
+		return err;
 
 	return 0;
 }
-- 
1.8.2.2



More information about the openbmc mailing list