From: Jacek Anaszewski <j.anaszewski@samsung.com>
To: "Álvaro Fernández Rojas" <noltari@gmail.com>
Cc: linux-leds@vger.kernel.org, devicetree@vger.kernel.org,
cooloney@gmail.com, jogo@openwrt.org, f.fainelli@gmail.com,
cernekee@gmail.com
Subject: Re: [PATCH 2/2] leds: add BCM6358 LED driver
Date: Thu, 21 May 2015 12:58:39 +0200 [thread overview]
Message-ID: <555DBA5F.9040906@samsung.com> (raw)
In-Reply-To: <1432055578-14089-3-git-send-email-noltari@gmail.com>
Hi Alvaro,
Please fix the issues reported by checkpatch --strict.
Besides I have one comment below.
On 05/19/2015 07:12 PM, Álvaro Fernández Rojas wrote:
> This adds support for the LED controller on Broadcom's BCM6358.
>
> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
> ---
> drivers/leds/Kconfig | 8 ++
> drivers/leds/Makefile | 1 +
> drivers/leds/leds-bcm6358.c | 241 ++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 250 insertions(+)
> create mode 100644 drivers/leds/leds-bcm6358.c
>
> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> index ec26dd1..86de046 100644
> --- a/drivers/leds/Kconfig
> +++ b/drivers/leds/Kconfig
> @@ -58,6 +58,14 @@ config LEDS_BCM6328
> This option enables support for LEDs connected to the BCM6328
> LED HW controller accessed via MMIO registers.
>
> +config LEDS_BCM6358
> + tristate "LED Support for Broadcom BCM6358"
> + depends on LEDS_CLASS
> + depends on OF
> + help
> + This option enables support for LEDs connected to the BCM6358
> + LED HW controller accessed via MMIO registers.
> +
> config LEDS_LM3530
> tristate "LCD Backlight driver for LM3530"
> depends on LEDS_CLASS
> diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
> index edb3abf..8d6a24a 100644
> --- a/drivers/leds/Makefile
> +++ b/drivers/leds/Makefile
> @@ -9,6 +9,7 @@ obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o
> obj-$(CONFIG_LEDS_88PM860X) += leds-88pm860x.o
> obj-$(CONFIG_LEDS_AAT1290) += leds-aat1290.o
> obj-$(CONFIG_LEDS_BCM6328) += leds-bcm6328.o
> +obj-$(CONFIG_LEDS_BCM6358) += leds-bcm6358.o
> obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o
> obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
> obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o
> diff --git a/drivers/leds/leds-bcm6358.c b/drivers/leds/leds-bcm6358.c
> new file mode 100644
> index 0000000..4a3a6c3
> --- /dev/null
> +++ b/drivers/leds/leds-bcm6358.c
> @@ -0,0 +1,241 @@
> +/*
> + * Driver for BCM6358 memory-mapped LEDs, based on leds-syscon.c
> + *
> + * Copyright 2015 Álvaro Fernández Rojas <noltari@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + */
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/leds.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/spinlock.h>
> +
> +#define BCM6358_REG_MODE 0x0
> +#define BCM6358_REG_CTRL 0x4
> +
> +#define BCM6358_SLED_CLKDIV_MASK 3
> +#define BCM6358_SLED_CLKDIV_1 0
> +#define BCM6358_SLED_CLKDIV_2 1
> +#define BCM6358_SLED_CLKDIV_4 2
> +#define BCM6358_SLED_CLKDIV_8 3
> +
> +#define BCM6358_SLED_POLARITY BIT(2)
> +#define BCM6358_SLED_BUSY BIT(3)
> +
> +#define BCM6358_SLED_MAX_COUNT 32
> +#define BCM6358_SLED_WAIT 100
> +
> +/**
> + * struct bcm6358_led - state container for bcm6358 based LEDs
> + * @cdev: LED class device for this LED
> + * @mem: memory resource
> + * @lock: memory lock
> + * @pin: LED pin number
> + * @active_low: LED is active low
> + */
> +struct bcm6358_led {
> + struct led_classdev cdev;
> + void __iomem *mem;
> + spinlock_t *lock;
> + unsigned long pin;
> + bool active_low;
> +};
> +
> +static void bcm6358_led_write(void __iomem *reg, unsigned long data)
> +{
> + iowrite32be(data, reg);
> +}
> +
> +static unsigned long bcm6358_led_read(void __iomem *reg)
> +{
> + return ioread32be(reg);
> +}
> +
> +static unsigned long bcm6358_led_busy(void __iomem *mem)
> +{
> + unsigned long val;
> +
> + while ((val = bcm6358_led_read(mem + BCM6358_REG_CTRL)) &
> + BCM6358_SLED_BUSY)
> + udelay(BCM6358_SLED_WAIT);
> +
> + return val;
> +}
> +
> +static void bcm6358_led_mode(struct bcm6358_led *led, unsigned long value)
> +{
> + unsigned long val;
> +
> + bcm6358_led_busy(led->mem);
> +
> + val = bcm6358_led_read(led->mem + BCM6358_REG_MODE);
> + if ((led->active_low && value == LED_OFF) ||
> + (!led->active_low && value != LED_OFF))
> + val |= BIT(led->pin);
> + else
> + val &= ~(BIT(led->pin));
> + bcm6358_led_write(led->mem + BCM6358_REG_MODE, val);
> +}
> +
> +static void bcm6358_led_set(struct led_classdev *led_cdev,
> + enum led_brightness value)
> +{
> + struct bcm6358_led *led =
> + container_of(led_cdev, struct bcm6358_led, cdev);
> + unsigned long flags;
> +
> + spin_lock_irqsave(led->lock, flags);
> + bcm6358_led_mode(led, value);
> + spin_unlock_irqrestore(led->lock, flags);
> +}
> +
> +static int bcm6358_led(struct device *dev, struct device_node *nc, u32 reg,
> + void __iomem *mem, spinlock_t *lock)
> +{
> + struct bcm6358_led *led;
> + unsigned long flags;
> + const char *state;
> + int rc;
> +
> + led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
> + if (!led)
> + return -ENOMEM;
> +
> + led->pin = reg;
> + led->mem = mem;
> + led->lock = lock;
> +
> + if (of_property_read_bool(nc, "active-low"))
> + led->active_low = true;
> +
> + led->cdev.name = of_get_property(nc, "label", NULL) ? : nc->name;
> + led->cdev.default_trigger = of_get_property(nc,
> + "linux,default-trigger",
> + NULL);
> +
> + spin_lock_irqsave(lock, flags);
> + if (!of_property_read_string(nc, "default-state", &state))
> + if (!strcmp(state, "on"))
> + led->cdev.brightness = LED_FULL;
> + else if (!strcmp(state, "keep")) {
> + unsigned long val;
> +
> + bcm6358_led_busy(led->mem);
> +
> + val = bcm6358_led_read(led->mem + BCM6358_REG_MODE);
> + val &= BIT(led->pin);
> + if ((led->active_low && !val) ||
> + (!led->active_low && val))
> + led->cdev.brightness = LED_FULL;
> + else
> + led->cdev.brightness = LED_OFF;
> + } else
> + led->cdev.brightness = LED_OFF;
> + else
> + led->cdev.brightness = LED_OFF;
> + bcm6358_led_mode(led, led->cdev.brightness);
> + spin_unlock_irqrestore(lock, flags);
> +
> + led->cdev.brightness_set = bcm6358_led_set;
> +
> + rc = led_classdev_register(dev, &led->cdev);
> + if (rc < 0)
> + return rc;
> +
> + dev_dbg(dev, "registered LED %s\n", led->cdev.name);
> +
> + return 0;
> +}
> +
> +static int bcm6358_leds_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *np = pdev->dev.of_node;
> + struct device_node *child;
> + struct resource *mem_r;
> + void __iomem *mem;
> + spinlock_t *lock;
> + unsigned long val;
> + u32 clk_div;
> +
> + mem_r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!mem_r)
> + return -EINVAL;
> +
> + mem = devm_ioremap_resource(dev, mem_r);
> + if (IS_ERR(mem))
> + return PTR_ERR(mem);
> +
> + lock = devm_kzalloc(dev, sizeof(*lock), GFP_KERNEL);
> + if (!lock)
> + return -ENOMEM;
> +
> + spin_lock_init(lock);
> +
> + val = bcm6358_led_busy(mem);
> + val &= ~(BCM6358_SLED_POLARITY | BCM6358_SLED_CLKDIV_MASK);
> + if (of_property_read_bool(np, "brcm,clk-dat-low"))
> + val |= BCM6358_SLED_POLARITY;
> + of_property_read_u32(child, "brcm,clk-div", &clk_div);
child is uninitialized here
> + switch (clk_div) {
> + case 8:
> + val |= BCM6358_SLED_CLKDIV_8;
> + break;
> + case 4:
> + val |= BCM6358_SLED_CLKDIV_4;
> + break;
> + case 2:
> + val |= BCM6358_SLED_CLKDIV_2;
> + break;
> + default:
> + val |= BCM6358_SLED_CLKDIV_1;
> + break;
> + }
> + bcm6358_led_write(mem + BCM6358_REG_CTRL, val);
> +
> + for_each_available_child_of_node(np, child) {
> + int rc;
> + u32 reg;
> +
> + if (of_property_read_u32(child, "reg", ®))
> + continue;
> +
> + if (reg >= BCM6358_SLED_MAX_COUNT) {
> + dev_err(dev, "invalid LED (%u >= %d)\n", reg,
> + BCM6358_SLED_MAX_COUNT);
> + continue;
> + }
> +
> + rc = bcm6358_led(dev, child, reg, mem, lock);
> + if (rc < 0)
> + return rc;
> + }
> +
> + return 0;
> +}
> +
> +static const struct of_device_id bcm6358_leds_of_match[] = {
> + { .compatible = "brcm,bcm6358-leds", },
> + { },
> +};
> +
> +static struct platform_driver bcm6358_leds_driver = {
> + .probe = bcm6358_leds_probe,
> + .driver = {
> + .name = "leds-bcm6358",
> + .of_match_table = bcm6358_leds_of_match,
> + },
> +};
> +
> +module_platform_driver(bcm6358_leds_driver);
> +
> +MODULE_AUTHOR("Álvaro Fernández Rojas <noltari@gmail.com>");
> +MODULE_DESCRIPTION("LED driver for BCM6358 controllers");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform:leds-bcm6358");
>
--
Best Regards,
Jacek Anaszewski
next prev parent reply other threads:[~2015-05-21 10:58 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-19 17:12 [PATCH 0/2] BCM6358 LED driver Álvaro Fernández Rojas
2015-05-19 17:12 ` [PATCH 1/2] leds: add DT binding for BCM6358 LED controller Álvaro Fernández Rojas
2015-05-21 11:01 ` Jacek Anaszewski
2015-05-19 17:12 ` [PATCH 2/2] leds: add BCM6358 LED driver Álvaro Fernández Rojas
2015-05-21 10:58 ` Jacek Anaszewski [this message]
2015-05-21 17:11 ` [PATCH v2 0/2] " Álvaro Fernández Rojas
2015-05-21 17:11 ` [PATCH v2 1/2] leds: add DT binding for BCM6358 LED controller Álvaro Fernández Rojas
2015-05-22 15:08 ` Jacek Anaszewski
2015-05-22 22:32 ` Bryan Wu
2015-05-21 17:11 ` [PATCH v2 2/2] leds: add BCM6358 LED driver Álvaro Fernández Rojas
2015-05-22 15:10 ` Jacek Anaszewski
2015-05-22 22:34 ` Bryan Wu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=555DBA5F.9040906@samsung.com \
--to=j.anaszewski@samsung.com \
--cc=cernekee@gmail.com \
--cc=cooloney@gmail.com \
--cc=devicetree@vger.kernel.org \
--cc=f.fainelli@gmail.com \
--cc=jogo@openwrt.org \
--cc=linux-leds@vger.kernel.org \
--cc=noltari@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.