← Back to team overview

touch-packages team mailing list archive

[Bug 1347776] Re: shutdown trigger on gpio_keys.X for armhf hardware

 

I added the keys sysfs attribute to gpio-keys-polled.c. Please try this
patch (should apply on ubuntu-linux 4.3).

diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c
index 11e77a9..3a8ee50 100644
--- a/drivers/input/keyboard/gpio_keys_polled.c
+++ b/drivers/input/keyboard/gpio_keys_polled.c
@@ -43,6 +43,85 @@ struct gpio_keys_polled_dev {
 	struct gpio_keys_button_data data[0];
 };
 
+/**
+ * get_n_events_by_type() - returns maximum number of events per @type
+ * @type: type of button (%EV_KEY, %EV_SW)
+ *
+ * Return value of this function can be used to allocate bitmap
+ * large enough to hold all bits for given type.
+ */
+static inline int get_n_events_by_type(int type)
+{
+	BUG_ON(type != EV_SW && type != EV_KEY);
+
+	return (type == EV_KEY) ? KEY_CNT : SW_CNT;
+}
+
+/**
+ * gpio_keys_polled_attr_show_helper() - fill in stringified bitmap of buttons
+ * @ddata: pointer to drvdata
+ * @buf: buffer where stringified bitmap is written
+ * @type: button type (%EV_KEY, %EV_SW)
+ *
+ * Returns 0 on success or negative errno on failure.
+ */
+static ssize_t gpio_keys_polled_attr_show_helper(
+						struct gpio_keys_polled_dev *ddata,
+						char *buf, unsigned int type)
+{
+	int n_events = get_n_events_by_type(type);
+	unsigned long *bits;
+	ssize_t ret;
+	int i;
+
+	bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL);
+	if (!bits)
+		return -ENOMEM;
+
+	for (i = 0; i < ddata->pdata->nbuttons; i++) {
+		struct gpio_keys_button *bdata = &ddata->pdata->buttons[i];
+
+		if (bdata->type != type)
+			continue;
+
+		__set_bit(bdata->code, bits);
+	}
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%*pbl", n_events, bits);
+	buf[ret++] = '\n';
+	buf[ret] = '\0';
+
+	kfree(bits);
+
+	return ret;
+}
+
+static ssize_t gpio_keys_polled_show_keys(struct device *dev,
+				     struct device_attribute *attr,
+				     char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct gpio_keys_polled_dev *ddata = platform_get_drvdata(pdev);
+
+	return gpio_keys_polled_attr_show_helper(ddata, buf, EV_KEY);
+}
+
+/*
+ * ATTRIBUTES:
+ *
+ * /sys/devices/platform/gpio-keys-polled/keys [ro]
+ */
+static DEVICE_ATTR(keys, S_IRUGO, gpio_keys_polled_show_keys, NULL);
+
+static struct attribute *gpio_keys_polled_attrs[] = {
+	&dev_attr_keys.attr,
+	NULL,
+};
+
+static struct attribute_group gpio_keys_polled_attr_group = {
+	.attrs = gpio_keys_polled_attrs,
+};
+
 static void gpio_keys_polled_check_state(struct input_dev *input,
 					 struct gpio_keys_button *button,
 					 struct gpio_keys_button_data *bdata)
@@ -286,6 +365,13 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
 	bdev->pdata = pdata;
 	platform_set_drvdata(pdev, bdev);
 
+	error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_polled_attr_group);
+	if (error) {
+		dev_err(dev, "Unable to export keys, error: %d\n",
+			error);
+		return error;
+	}
+
 	error = input_register_polled_device(poll_dev);
 	if (error) {
 		dev_err(dev, "unable to register polled device, err=%d\n",

-- 
You received this bug notification because you are a member of Ubuntu
Touch seeded packages, which is subscribed to systemd in Ubuntu.
https://bugs.launchpad.net/bugs/1347776

Title:
  shutdown trigger on gpio_keys.X for armhf hardware

Status in systemd:
  Confirmed
Status in systemd package in Ubuntu:
  Fix Released
Status in systemd source package in Trusty:
  Fix Released
Status in systemd source package in Utopic:
  Fix Released

Bug description:
  Some ARM board uses GPIO gpio_key.12 for power control (key=116). The
  proposed patch adds entry to logind's 70-power-switch.rules to
  initiate soft shutdown of the cartridge from ilo.

  Here is the udevadm output for /dev/input/event0

  sudo udevadm info --query=all --name=/dev/input/event0 --attribute-
  walk

  Udevadm info starts with the device specified by the devpath and then
  walks up the chain of parent devices. It prints for every device
  found, all possible attributes in the udev rules key format.
  A rule to match, can be composed by the attributes of the device
  and the attributes from one single parent device.

    looking at device '/devices/soc.3/gpio_keys.12/input/input0/event0':
      KERNEL=="event0"
      SUBSYSTEM=="input"
      DRIVER==""

    looking at parent device '/devices/soc.3/gpio_keys.12/input/input0':
      KERNELS=="input0"
      SUBSYSTEMS=="input"
      DRIVERS==""
      ATTRS{name}=="gpio_keys.12"
      ATTRS{phys}=="gpio-keys/input0"
      ATTRS{uniq}==""
      ATTRS{properties}=="0"

    looking at parent device '/devices/soc.3/gpio_keys.12':
      KERNELS=="gpio_keys.12"
      SUBSYSTEMS=="platform"
      DRIVERS=="gpio-keys"
      ATTRS{keys}=="116"
      ATTRS{switches}==""
      ATTRS{disabled_keys}==""
      ATTRS{disabled_switches}==""

    looking at parent device '/devices/soc.3':
      KERNELS=="soc.3"
      SUBSYSTEMS=="platform"
      DRIVERS==""

  Regarding the possibility of gpio_key.12 being used by other systems
  to map to some other trigger, I put in the check that the gpio_key.12
  is associated with power control (keys=116). '116' is supposedly linux
  generic power control in DTS. There is no uniq idSystem or idVendor
  for device /dev/input/event0 as you can see from udevadm output,
  therefore I tried to use the best available combination as a safety
  check. This patch will enable power control for any system vendor
  (Other than the one the patch in intended for) that describes in DTS,
  the trigger gpio_key.12 as power control (116).

  
  SRU Request
  ==========

  [Impact]

  * User won't be able to initiate a soft shutdown from the chassis
  manager.

  [Test Case]

  * To reproduce this bug, initiate a soft shutdown from the chassis manager, for example from ilo you could do
  <ilo> set node power off shutdown <node number>

  [Test Result]

  == BEFORE PATCH ==

  $ cat /lib/udev/rules.d/70-power-switch.rules
  # This file is part of systemd.
  #
  # systemd is free software; you can redistribute it and/or modify it
  # under the terms of the GNU Lesser General Public License as published by
  # the Free Software Foundation; either version 2.1 of the License, or
  # (at your option) any later version.

  ACTION=="remove", GOTO="power_switch_end"

  SUBSYSTEM=="input", KERNEL=="event*", SUBSYSTEMS=="acpi", TAG+="power-switch"
  SUBSYSTEM=="input", KERNEL=="event*", KERNELS=="thinkpad_acpi", TAG+="power-switch"

  LABEL="power_switch_end"
  $

  </>hpiLO-> set node power off shutdown c3n2

    c3: #Cartridge 3
      c3n2: #Node 2 Shutting node down gracefully

  hpiLO-> show node list

  Slot ID Proc Manufacturer Architecture Memory Power Health
  ---- ----- ---------------------- -------------------- ------ ----- ------
    3 c3n1 **** ARM Architecture 8 GB On OK
    3 c3n2 **** ARM Architecture 8 GB On OK
    3 c3n3 **** ARM Architecture 8 GB On OK
    3 c3n4 **** ARM Architecture 8 GB Off OK

  hpiLO->

  == AFTER PATCH ==

  hpiLO-> set node power off shutdown c3n1

    c3: #Cartridge 3
      c3n1: #Node 1 Shutting node down gracefully

  hpiLO-> show node list

  Slot ID Proc Manufacturer Architecture Memory Power Health
  ---- ----- ---------------------- -------------------- ------ ----- ------
    3 c3n1 **** ARM Architecture 8 GB Off OK
    3 c3n2 **** ARM Architecture 8 GB On OK
    3 c3n3 **** ARM Architecture 8 GB On OK
    3 c3n4 **** ARM Architecture 8 GB Off OK

  hpiLO->

  [Regression Potential]

  None.
  Note: Regarding the possibility of gpio_key.12 being used by other systems to map to some other trigger, I put in the check that the gpio_key.12 is associated with power control (keys=116). '116' is supposedly linux generic power control in DTS.

To manage notifications about this bug go to:
https://bugs.launchpad.net/systemd/+bug/1347776/+subscriptions