Skip to contentSkip to conversation

gpio: add MSIC gpio driver

PATCH RESEND In review Alan Cox 2 participants 3 messages Apr 10, 2012 GPIO

lore
Share & tools
lore

Alan Cox

author
#0 lore raw

PATCH RESEND 1/1 gpio: add MSIC gpio driver

Resending as no response received.

From: Mathias Nyman <[email protected]>

Add gpio support for Intel MSIC chips found in Intel Medfield platforms. MSIC supports totally 24 GPIOs with 16 low voltage and 8 high voltage pins. Driver uses MSIC mfd interface for MSIC access.

---

 drivers/gpio/Kconfig     |    8 +
 drivers/gpio/Makefile    |    1 
 drivers/gpio/gpio-msic.c |  336 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 345 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpio/gpio-msic.c
drivers/gpio/Kconfig +8 -0
index e03653d..9526f24 100644
@@ -514,4 +514,12 @@ config GPIO_TPS65910
 	help
 	  Select this option to enable GPIO driver for the TPS65910
 	  chip family.
+
+config GPIO_MSIC
+	bool "Intel MSIC mixed signal gpio support"
+	depends on MFD_INTEL_MSIC
+	help
+	  Enable support for GPIO on intel MSIC controllers found in
+	  intel MID devices
+
 endif
drivers/gpio/Makefile +1 -0
index 007f54b..3ed0146 100644
@@ -32,6 +32,7 @@ obj-$(CONFIG_GPIO_MCP23S08)	+= gpio-mcp23s08.o
 obj-$(CONFIG_GPIO_ML_IOH)	+= gpio-ml-ioh.o
 obj-$(CONFIG_GPIO_MPC5200)	+= gpio-mpc5200.o
 obj-$(CONFIG_GPIO_MPC8XXX)	+= gpio-mpc8xxx.o
+obj-$(CONFIG_GPIO_MSIC)		+= gpio-msic.o
 obj-$(CONFIG_GPIO_MSM_V1)	+= gpio-msm-v1.o
 obj-$(CONFIG_GPIO_MSM_V2)	+= gpio-msm-v2.o
 obj-$(CONFIG_GPIO_MXC)		+= gpio-mxc.o
drivers/gpio/gpio-msic.c new file +336 -0

336 lines not on this page · raw message

#1 lore raw
Quoted 5 lines · Alan Cox
drivers/gpio/gpio-msic.c new file +5 -0
+	if (mg->trig_change_mask) {
+		offset = __ffs(mg->trig_change_mask);
+
+		reg = msic_gpio_to_ireg(offset);
+		if (reg < 0)

drivers/gpio/gpio-msic.c line 213

Quoted 10 lines
drivers/gpio/gpio-msic.c new file +10 -0
+			goto out;
+
+		if (mg->trig_type & IRQ_TYPE_EDGE_RISING)
+			trig |= MSIC_GPIO_TRIG_RISE;
+		if (mg->trig_type & IRQ_TYPE_EDGE_FALLING)
+			trig |= MSIC_GPIO_TRIG_FALL;
+
+		intel_msic_reg_update(reg, trig, MSIC_GPIO_INTCNT_MASK);
+		mg->trig_change_mask = 0;
+	}

What happens if we manage to get more than one change flagged while the lock is held?

drivers/gpio/gpio-msic.c line 221

Quoted 4 lines
drivers/gpio/gpio-msic.c new file +3 -0
+/* Firmware does all the masking and unmasking for us, no masking here. */
+static void msic_irq_unmask(struct irq_data *data) { }
 
+static void msic_irq_mask(struct irq_data *data) { }

Shouldn't these just be omitted if they don't do anything (or alternatively, how does the firmware figure out that it needs to do the masking and unmasking)?

drivers/gpio/gpio-msic.c line 277

Quoted 3 lines
drivers/gpio/gpio-msic.c new file +3 -0
+	mg = kzalloc(sizeof(*mg), GFP_KERNEL);
+	if (!mg)
+		return -ENOMEM;

devm_kzalloc()

author
#2 lore raw
Quoted 12 lines · On Tue, 10 Apr 2012 14:10:56 +0100 Mark Brown…
Quoted 10 lines · Alan Cox
drivers/gpio/gpio-msic.c new file +10 -0
+	if (mg->trig_change_mask) {
+		offset = __ffs(mg->trig_change_mask);
+
+		reg = msic_gpio_to_ireg(offset);
+		if (reg < 0)
+			goto out;
+
+		if (mg->trig_type & IRQ_TYPE_EDGE_RISING)
+			trig |= MSIC_GPIO_TRIG_RISE;
+		if (mg->trig_type & IRQ_TYPE_EDGE_FALLING)
Quoted 8 lines

drivers/gpio/gpio-msic.c line 213

Quoted 5 lines
drivers/gpio/gpio-msic.c new file +5 -0
+			trig |= MSIC_GPIO_TRIG_FALL;
+
+		intel_msic_reg_update(reg, trig, MSIC_GPIO_INTCNT_MASK);
+		mg->trig_change_mask = 0;
+	}

What happens if we manage to get more than one change flagged while the lock is held?

It breaks. 8-). I will take a look at that.

Quoted 8 lines

drivers/gpio/gpio-msic.c line 221

Quoted 4 lines
drivers/gpio/gpio-msic.c new file +3 -0
+/* Firmware does all the masking and unmasking for us, no masking here. */
+static void msic_irq_unmask(struct irq_data *data) { }
 
+static void msic_irq_mask(struct irq_data *data) { }

Shouldn't these just be omitted if they don't do anything (or alternatively, how does the firmware figure out that it needs to do the masking and unmasking)?

The IRQ layer requires they are present and calls them without NULL checks on many paths. I imagine it's better for the normal cases to avoid the conditional checks on those fast paths.

The gpio code is talking to the firmware controller (via intel_msic_reg_*) and effectively its poking GPIOs on a separate device via a messaging interface.

I'll go fix the type change to just keep a per gpio type.

Quoted 5 lines

drivers/gpio/gpio-msic.c line 277

Quoted 3 lines
drivers/gpio/gpio-msic.c new file +3 -0
+	mg = kzalloc(sizeof(*mg), GFP_KERNEL);
+	if (!mg)
+		return -ENOMEM;

devm_kzalloc()

No point - the driver isn't unloadable. Nor does it make sense to make it so.

Alan