<feed xmlns='http://www.w3.org/2005/Atom'>
<title>talos-obmc-linux/drivers/leds, branch dev-4.13</title>
<subtitle>Talos™ II Linux sources for OpenBMC</subtitle>
<id>https://git.raptorcs.com/git/talos-obmc-linux/atom?h=dev-4.13</id>
<link rel='self' href='https://git.raptorcs.com/git/talos-obmc-linux/atom?h=dev-4.13'/>
<link rel='alternate' type='text/html' href='https://git.raptorcs.com/git/talos-obmc-linux/'/>
<updated>2017-11-28T04:37:45+00:00</updated>
<entry>
<title>leds: pca955x: Don't invert requested value in pca955x_gpio_set_value()</title>
<updated>2017-11-28T04:37:45+00:00</updated>
<author>
<name>Andrew Jeffery</name>
<email>andrew@aj.id.au</email>
</author>
<published>2017-09-01T05:38:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.raptorcs.com/git/talos-obmc-linux/commit/?id=bc2c536f0361d7ea21f54258c02e43424d2ee443'/>
<id>urn:sha1:bc2c536f0361d7ea21f54258c02e43424d2ee443</id>
<content type='text'>
The PCA9552 lines can be used either for driving LEDs or as GPIOs. The
manual states that for LEDs, the operation is open-drain:

         The LSn LED select registers determine the source of the LED data.

           00 = output is set LOW (LED on)
           01 = output is set high-impedance (LED off; default)
           10 = output blinks at PWM0 rate
           11 = output blinks at PWM1 rate

For GPIOs it suggests a pull-up so that the open-case drives the line
high:

         For use as output, connect external pull-up resistor to the pin
         and size it according to the DC recommended operating
         characteristics.  LED output pin is HIGH when the output is
         programmed as high-impedance, and LOW when the output is
         programmed LOW through the ‘LED selector’ register.  The output
         can be pulse-width controlled when PWM0 or PWM1 are used.

Now, I have a hardware design that uses the LED controller to control
LEDs. However, for $reasons, we're using the leds-gpio driver to drive
the them. The reasons are here are a tangent but lead to the discovery
of the inversion, which manifested as the LEDs being set to full
brightness at boot when we expected them to be off.

As we're driving the LEDs through leds-gpio, this means wending our way
through the gpiochip abstractions. So with that in mind we need to
describe an active-low GPIO configuration to drive the LEDs as though
they were GPIOs.

The set() gpiochip callback in leds-pca955x does the following:

         ...
         if (val)
                pca955x_led_set(&amp;led-&gt;led_cdev, LED_FULL);
         else
                pca955x_led_set(&amp;led-&gt;led_cdev, LED_OFF);
         ...

Where LED_FULL = 255. pca955x_led_set() in turn does:

         ...
         switch (value) {
         case LED_FULL:
                ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_LED_ON);
                break;
         ...

Where PCA955X_LS_LED_ON is defined as:

         #define PCA955X_LS_LED_ON	0x0	/* Output LOW */

So here we have some type confusion: We've crossed domains from GPIO
behaviour to LED behaviour without accounting for possible inversions
in the process.

Stepping back to leds-gpio for a moment, during probe() we call
create_gpio_led(), which eventually executes:

         if (template-&gt;default_state == LEDS_GPIO_DEFSTATE_KEEP) {
                state = gpiod_get_value_cansleep(led_dat-&gt;gpiod);
                if (state &lt; 0)
                        return state;
         } else {
                state = (template-&gt;default_state == LEDS_GPIO_DEFSTATE_ON);
         }
         ...
         ret = gpiod_direction_output(led_dat-&gt;gpiod, state);

In the devicetree the GPIO is annotated as active-low, and
gpiod_get_value_cansleep() handles this for us:

         int gpiod_get_value_cansleep(const struct gpio_desc *desc)
         {
                 int value;

                 might_sleep_if(extra_checks);
                 VALIDATE_DESC(desc);
                 value = _gpiod_get_raw_value(desc);
                 if (value &lt; 0)
                         return value;

                 if (test_bit(FLAG_ACTIVE_LOW, &amp;desc-&gt;flags))
                         value = !value;

                 return value;
         }

_gpiod_get_raw_value() in turn calls through the get() callback for the
gpiochip implementation, so returning to our get() implementation in
leds-pca955x we find we extract the raw value from hardware:

         static int pca955x_gpio_get_value(struct gpio_chip *gc, unsigned int offset)
         {
                 struct pca955x *pca955x = gpiochip_get_data(gc);
                 struct pca955x_led *led = &amp;pca955x-&gt;leds[offset];
                 u8 reg = pca955x_read_input(pca955x-&gt;client, led-&gt;led_num / 8);

                 return !!(reg &amp; (1 &lt;&lt; (led-&gt;led_num % 8)));
         }

This behaviour is not symmetric with that of set(), where the val is
inverted by the driver.

Closing the loop on the GPIO_ACTIVE_LOW inversions,
gpiod_direction_output(), like gpiod_get_value_cansleep(), handles it
for us:

         int gpiod_direction_output(struct gpio_desc *desc, int value)
         {
                  VALIDATE_DESC(desc);
                  if (test_bit(FLAG_ACTIVE_LOW, &amp;desc-&gt;flags))
                           value = !value;
                  else
                           value = !!value;
                  return _gpiod_direction_output_raw(desc, value);
         }

All-in-all, with a value of 'keep' for default-state property in a
leds-gpio child node, the current state of the hardware will in-fact be
inverted; precisely the opposite of what was intended.

Rework leds-pca955x so that we avoid the incorrect inversion and clarify
the semantics with respect to GPIO.

Signed-off-by: Andrew Jeffery &lt;andrew@aj.id.au&gt;
Reviewed-by: Cédric Le Goater &lt;clg@kaod.org&gt;
Tested-by: Joel Stanley &lt;joel@jms.id.au&gt;
Tested-by: Matt Spinler &lt;mspinler@linux.vnet.ibm.com&gt;
Signed-off-by: Jacek Anaszewski &lt;jacek.anaszewski@gmail.com&gt;
(cherry picked from commit 52ca7d0f7bdad832b291ed979146443533ee79c0)
Signed-off-by: Joel Stanley &lt;joel@jms.id.au&gt;
</content>
</entry>
<entry>
<title>leds: pca955x: check for I2C errors</title>
<updated>2017-11-28T04:37:44+00:00</updated>
<author>
<name>Cédric Le Goater</name>
<email>clg@kaod.org</email>
</author>
<published>2017-08-30T11:25:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.raptorcs.com/git/talos-obmc-linux/commit/?id=f8901100bd1b1e5ac8f3346772c1f0249fb0225d'/>
<id>urn:sha1:f8901100bd1b1e5ac8f3346772c1f0249fb0225d</id>
<content type='text'>
This should also allow probing to fail when a pca955x chip is not
found on a I2C bus.

Signed-off-by: Cédric Le Goater &lt;clg@kaod.org&gt;
Signed-off-by: Jacek Anaszewski &lt;jacek.anaszewski@gmail.com&gt;
(cherry picked from commit 1591caf2d5eafdfb3b300691f8f99e5bb97d5406)
Signed-off-by: Joel Stanley &lt;joel@jms.id.au&gt;
</content>
</entry>
<entry>
<title>leds: pca955x: Prevent crippled LED device name</title>
<updated>2017-11-28T04:37:44+00:00</updated>
<author>
<name>Jacek Anaszewski</name>
<email>jacek.anaszewski@gmail.com</email>
</author>
<published>2017-08-17T20:16:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.raptorcs.com/git/talos-obmc-linux/commit/?id=70bc28b6752976d8d6ae50e82d17bfc171a8f17f'/>
<id>urn:sha1:70bc28b6752976d8d6ae50e82d17bfc171a8f17f</id>
<content type='text'>
In case platform data provided empty LED name string the resulting
LED class device name would be crippled. Use corresponding LED chip
bit in place of "function" segment of LED class device name then to
make the LEDs at least distinguishable.

Signed-off-by: Jacek Anaszewski &lt;jacek.anaszewski@gmail.com&gt;
Reported-by: Colin King &lt;colin.king@canonical.com&gt;
Reported-by: Dan Carpenter &lt;dan.carpenter@oracle.com&gt;
Suggested-by: Nate Case &lt;ncase@xes-inc.com&gt;
(cherry picked from commit 390c97dc6e346b65df61c18fade67577896382fd)
Signed-off-by: Joel Stanley &lt;joel@jms.id.au&gt;
</content>
</entry>
<entry>
<title>leds: pca955x: add GPIO support</title>
<updated>2017-11-28T04:37:43+00:00</updated>
<author>
<name>Cédric Le Goater</name>
<email>clg@kaod.org</email>
</author>
<published>2017-08-08T13:42:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.raptorcs.com/git/talos-obmc-linux/commit/?id=ee7a4b1212541b3b0610ba189bf9f1d7aa41ccea'/>
<id>urn:sha1:ee7a4b1212541b3b0610ba189bf9f1d7aa41ccea</id>
<content type='text'>
The PCA955x family of chips are I2C LED blinkers whose pins not used
to control LEDs can be used as general purpose I/Os (GPIOs).

The following adds such a support by defining different operation
modes for the pins (See bindings documentation for more details). The
pca955x driver is then extended with a gpio_chip when some of pins are
operating as GPIOs. The default operating mode is to behave as a LED.

The GPIO support is conditioned by CONFIG_LEDS_PCA955X_GPIO.

Signed-off-by: Cédric Le Goater &lt;clg@kaod.org&gt;
Acked-by: Pavel Machek &lt;pavel@ucw.cz&gt;
Signed-off-by: Jacek Anaszewski &lt;jacek.anaszewski@gmail.com&gt;
(cherry picked from commit 561099a1a2e992a482a8318c0c9c5af26222e5cd)
Signed-off-by: Joel Stanley &lt;joel@jms.id.au&gt;
</content>
</entry>
<entry>
<title>leds: pca955x: use devm_led_classdev_register</title>
<updated>2017-11-28T04:37:43+00:00</updated>
<author>
<name>Cédric Le Goater</name>
<email>clg@kaod.org</email>
</author>
<published>2017-08-08T13:42:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.raptorcs.com/git/talos-obmc-linux/commit/?id=a9376f34e0a6f615228982531a180f9e03dfeddf'/>
<id>urn:sha1:a9376f34e0a6f615228982531a180f9e03dfeddf</id>
<content type='text'>
This lets us remove the loop doing the cleanup in case of failure and
also the remove handler of the i2c_driver.

Signed-off-by: Cédric Le Goater &lt;clg@kaod.org&gt;
Acked-by: Pavel Machek &lt;pavel@ucw.cz&gt;
Signed-off-by: Jacek Anaszewski &lt;jacek.anaszewski@gmail.com&gt;
(cherry picked from commit 91940bb4ca7b7f1b5426cc14bdbd0c7f8347683f)
Signed-off-by: Joel Stanley &lt;joel@jms.id.au&gt;
</content>
</entry>
<entry>
<title>leds: pca955x: add device tree support</title>
<updated>2017-11-28T04:37:42+00:00</updated>
<author>
<name>Cédric Le Goater</name>
<email>clg@kaod.org</email>
</author>
<published>2017-08-08T13:42:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.raptorcs.com/git/talos-obmc-linux/commit/?id=4a8dbcd714cffc43050d69fe426ff6ffbd919628'/>
<id>urn:sha1:4a8dbcd714cffc43050d69fe426ff6ffbd919628</id>
<content type='text'>
It will be used in a following patch to define different operation
modes for each pin.

Signed-off-by: Cédric Le Goater &lt;clg@kaod.org&gt;
Acked-by: Pavel Machek &lt;pavel@ucw.cz&gt;
Signed-off-by: Jacek Anaszewski &lt;jacek.anaszewski@gmail.com&gt;
(cherry picked from commit ed1f4b9676a8eb9c38cf44cdc06300604bfbb43e)
Signed-off-by: Joel Stanley &lt;joel@jms.id.au&gt;
</content>
</entry>
<entry>
<title>leds: gpio: Allow LED to retain state at shutdown</title>
<updated>2017-11-28T04:22:52+00:00</updated>
<author>
<name>Andrew Jeffery</name>
<email>andrew@aj.id.au</email>
</author>
<published>2017-08-28T00:17:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.raptorcs.com/git/talos-obmc-linux/commit/?id=2f2306613e671b0d9d64980b9d328f1c5f7dad58'/>
<id>urn:sha1:2f2306613e671b0d9d64980b9d328f1c5f7dad58</id>
<content type='text'>
In some systems, such as Baseboard Management Controllers (BMCs), we
want to retain the state of LEDs across a reboot of the BMC (whilst the
host remains up). Implement support for the retain-state-shutdown
devicetree property in leds-gpio.

Signed-off-by: Andrew Jeffery &lt;andrew@aj.id.au&gt;
Acked-by: Pavel Machek &lt;pavel@ucw.cz&gt;
Tested-by: Brandon Wyman &lt;bjwyman@gmail.com&gt;
Signed-off-by: Jacek Anaszewski &lt;jacek.anaszewski@gmail.com&gt;
(cherry picked from commit f5808ac158f2b16b686a3d3c0879c5d6048aba14)
Signed-off-by: Joel Stanley &lt;joel@jms.id.au&gt;
</content>
</entry>
<entry>
<title>Merge tag 'leds_for_4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds</title>
<updated>2017-07-06T18:32:40+00:00</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2017-07-06T18:32:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.raptorcs.com/git/talos-obmc-linux/commit/?id=4f5dfdd29065a0d1d0e61d9744e14d1d852518be'/>
<id>urn:sha1:4f5dfdd29065a0d1d0e61d9744e14d1d852518be</id>
<content type='text'>
Pull LED updates from Jacek Anaszewski:
 "This time we're removing more than adding:

  Removed drivers:

    leds-versatile:
      - all users of the Versatile LED driver are deleted and replaced
        with the very generic leds-syscon

    leds-sead3:
      - SEAD3 is using the generic leds-syscon &amp; regmap based
        register-bit-led driver

  LED class drivers improvements:

    ledtrig-gpio:
      - use threaded IRQ, which both simplifies the code because we can
        drop the workqueue indirection, and it enables using the trigger
        for GPIOs that work with threaded IRQs themselves
      - refresh LED state after GPIO change since the new GPIO may have
        a different state than the old one

    leds-lp55xx:
      - make various arrays static const

    leds-pca963x:
      - add bindings to invert polarity"

* tag 'leds_for_4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds:
  leds: lp55xx: make various arrays static const
  leds: Remove SEAD-3 driver
  leds: trigger: gpio: Use threaded IRQ
  leds: trigger: gpio: Refresh LED state after GPIO change
  leds: Delete obsolete Versatile driver
  leds: pca963x: Add bindings to invert polarity
</content>
</entry>
<entry>
<title>leds: lp55xx: make various arrays static const</title>
<updated>2017-06-30T21:15:44+00:00</updated>
<author>
<name>Colin Ian King</name>
<email>colin.king@canonical.com</email>
</author>
<published>2017-06-29T17:57:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.raptorcs.com/git/talos-obmc-linux/commit/?id=4d1707c1c6901906707b9419cac8d9c84bc17d88'/>
<id>urn:sha1:4d1707c1c6901906707b9419cac8d9c84bc17d88</id>
<content type='text'>
Several arrays are currently on-stack and instead should be made
static const.

Signed-off-by: Colin Ian King &lt;colin.king@canonical.com&gt;
Acked-by: Pavel Machek &lt;pavel@ucw.cz&gt;
Signed-off-by: Jacek Anaszewski &lt;jacek.anaszewski@gmail.com&gt;
</content>
</entry>
<entry>
<title>Merge tag 'v4.12-rc6' into patchwork</title>
<updated>2017-06-20T11:51:56+00:00</updated>
<author>
<name>Mauro Carvalho Chehab</name>
<email>mchehab@s-opensource.com</email>
</author>
<published>2017-06-20T11:51:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.raptorcs.com/git/talos-obmc-linux/commit/?id=ff6ccad361df4dfda42b60897cb7e55b3ba13439'/>
<id>urn:sha1:ff6ccad361df4dfda42b60897cb7e55b3ba13439</id>
<content type='text'>
Linux 4.12-rc6

* tag 'v4.12-rc6': (813 commits)
  Linux 4.12-rc6
  mm: larger stack guard gap, between vmas
  virtio_balloon: disable VIOMMU support
  mm: correct the comment when reclaimed pages exceed the scanned pages
  userfaultfd: shmem: handle coredumping in handle_userfault()
  mm: numa: avoid waiting on freed migrated pages
  swap: cond_resched in swap_cgroup_prepare()
  mm/memory-failure.c: use compound_head() flags for huge pages
  perf unwind: Report module before querying isactivation in dwfl unwind
  fs: pass on flags in compat_writev
  objtool: Add fortify_panic as __noreturn function
  powerpc/debug: Add missing warn flag to WARN_ON's non-builtin path
  USB: gadgetfs, dummy-hcd, net2280: fix locking for callbacks
  drm: mxsfb_crtc: Reset the eLCDIF controller
  drm/mgag200: Fix to always set HiPri for G200e4 V2
  i2c: ismt: fix wrong device address when unmap the data buffer
  i2c: rcar: use correct length when unmapping DMA
  powerpc/xive: Fix offset for store EOI MMIOs
  drm/tegra: Correct idr_alloc() minimum id
  drm/tegra: Fix lockup on a use of staging API
  ...

Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@s-opensource.com&gt;
</content>
</entry>
</feed>
