diff options
author | Paul Gortmaker <paul.gortmaker@windriver.com> | 2018-08-01 15:48:50 -0400 |
---|---|---|
committer | Paul Gortmaker <paul.gortmaker@windriver.com> | 2018-08-01 15:48:50 -0400 |
commit | 8b086ef99b99c7f000a2c277e3ac4a1b398d3303 (patch) | |
tree | f0197a4e48b8af8f293cb209a6f84e61748b1589 | |
parent | 8c1f80c8da01ea1ee5f18a93ce8e3ce8000eb461 (diff) | |
download | longterm-queue-4.12-8b086ef99b99c7f000a2c277e3ac4a1b398d3303.tar.gz |
leds: drop patch n/a for 4.12.x
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r-- | queue/leds-pca955x-Don-t-invert-requested-value-in-pca955x.patch | 188 | ||||
-rw-r--r-- | queue/series | 1 |
2 files changed, 0 insertions, 189 deletions
diff --git a/queue/leds-pca955x-Don-t-invert-requested-value-in-pca955x.patch b/queue/leds-pca955x-Don-t-invert-requested-value-in-pca955x.patch deleted file mode 100644 index 417208b..0000000 --- a/queue/leds-pca955x-Don-t-invert-requested-value-in-pca955x.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 52ca7d0f7bdad832b291ed979146443533ee79c0 Mon Sep 17 00:00:00 2001 -From: Andrew Jeffery <andrew@aj.id.au> -Date: Fri, 1 Sep 2017 15:08:58 +0930 -Subject: [PATCH] leds: pca955x: Don't invert requested value in - pca955x_gpio_set_value() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -commit 52ca7d0f7bdad832b291ed979146443533ee79c0 upstream. - -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(&led->led_cdev, LED_FULL); - else - pca955x_led_set(&led->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->default_state == LEDS_GPIO_DEFSTATE_KEEP) { - state = gpiod_get_value_cansleep(led_dat->gpiod); - if (state < 0) - return state; - } else { - state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); - } - ... - ret = gpiod_direction_output(led_dat->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 < 0) - return value; - - if (test_bit(FLAG_ACTIVE_LOW, &desc->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 = &pca955x->leds[offset]; - u8 reg = pca955x_read_input(pca955x->client, led->led_num / 8); - - return !!(reg & (1 << (led->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, &desc->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 <andrew@aj.id.au> -Reviewed-by: Cédric Le Goater <clg@kaod.org> -Tested-by: Joel Stanley <joel@jms.id.au> -Tested-by: Matt Spinler <mspinler@linux.vnet.ibm.com> -Signed-off-by: Jacek Anaszewski <jacek.anaszewski@gmail.com> - -diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c -index 905729191d3e..78183f90820e 100644 ---- a/drivers/leds/leds-pca955x.c -+++ b/drivers/leds/leds-pca955x.c -@@ -61,6 +61,10 @@ - #define PCA955X_LS_BLINK0 0x2 /* Blink at PWM0 rate */ - #define PCA955X_LS_BLINK1 0x3 /* Blink at PWM1 rate */ - -+#define PCA955X_GPIO_INPUT LED_OFF -+#define PCA955X_GPIO_HIGH LED_OFF -+#define PCA955X_GPIO_LOW LED_FULL -+ - enum pca955x_type { - pca9550, - pca9551, -@@ -329,9 +333,9 @@ static int pca955x_set_value(struct gpio_chip *gc, unsigned int offset, - struct pca955x_led *led = &pca955x->leds[offset]; - - if (val) -- return pca955x_led_set(&led->led_cdev, LED_FULL); -- else -- return pca955x_led_set(&led->led_cdev, LED_OFF); -+ return pca955x_led_set(&led->led_cdev, PCA955X_GPIO_HIGH); -+ -+ return pca955x_led_set(&led->led_cdev, PCA955X_GPIO_LOW); - } - - static void pca955x_gpio_set_value(struct gpio_chip *gc, unsigned int offset, -@@ -355,8 +359,11 @@ static int pca955x_gpio_get_value(struct gpio_chip *gc, unsigned int offset) - static int pca955x_gpio_direction_input(struct gpio_chip *gc, - unsigned int offset) - { -- /* To use as input ensure pin is not driven */ -- return pca955x_set_value(gc, offset, 0); -+ struct pca955x *pca955x = gpiochip_get_data(gc); -+ struct pca955x_led *led = &pca955x->leds[offset]; -+ -+ /* To use as input ensure pin is not driven. */ -+ return pca955x_led_set(&led->led_cdev, PCA955X_GPIO_INPUT); - } - - static int pca955x_gpio_direction_output(struct gpio_chip *gc, --- -2.15.0 - diff --git a/queue/series b/queue/series index 6d124b1..a6953a5 100644 --- a/queue/series +++ b/queue/series @@ -20,7 +20,6 @@ ixgbe-fix-use-of-uninitialized-padding.patch IB-rxe-check-for-allocation-failure-on-elem.patch block-bfq-Disable-writeback-throttling.patch md-always-set-THREAD_WAKEUP-and-wake-up-wqueue-if-th.patch -leds-pca955x-Don-t-invert-requested-value-in-pca955x.patch Bluetooth-hci_uart_set_flow_control-Fix-NULL-deref-w.patch Bluetooth-hci_bcm-Fix-setting-of-irq-trigger-type.patch i40e-i40evf-spread-CPU-affinity-hints-across-online-.patch |