All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2017-12-26 15:07 [PATCH 1/3] Bluetooth: hci_bcm: Support Apple GPIO handling Lukas Wunner
@ 2017-12-26 15:07 ` Lukas Wunner
  2017-12-26 20:57   ` Marcel Holtmann
  2017-12-28  8:41   ` Andy Shevchenko
  2017-12-26 15:07 ` [PATCH 2/3] Bluetooth: hci_bcm: Streamline runtime PM code Lukas Wunner
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 27+ messages in thread
From: Lukas Wunner @ 2017-12-26 15:07 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg
  Cc: Mika Westerberg, Andy Shevchenko, Frederic Danis, Loic Poulain,
	Hans de Goede, Max Shavrick, Leif Liddy, Daniel Roschka,
	Ronald Tschalaer, Peter Y. Chuang, linux-bluetooth

Loading hci_bcm with CONFIG_GPIOLIB=n results in the following splat
when calling gpiod_to_irq() from bcm_get_resources():

    WARNING: CPU: 0 PID: 1006 at ./include/linux/gpio/consumer.h:450 bcm_get_resources+0x50/0x80
    CPU: 0 PID: 1006 Comm: kworker/u8:4 Tainted: G       A         4.15.0-rc4custom+ #4
    Hardware name: Apple Inc. MacBook8,1/Mac-BE0E8AC46FE800CC, BIOS MB81.88Z.0168.B00.1708080033 08/08/2017
    Call Trace:
    bcm_serdev_probe+0x8b/0xc0
    driver_probe_device+0x202/0x310
    __driver_attach+0x85/0x90
    ? driver_probe_device+0x310/0x310
    bus_for_each_dev+0x57/0x80
    async_run_entry_fn+0x2c/0xd0
    process_one_work+0x1d2/0x3d0
    worker_thread+0x26/0x3c0
    ? process_one_work+0x3d0/0x3d0
    kthread+0x10c/0x130
    ? kthread_create_on_node+0x40/0x40
    ret_from_fork+0x1f/0x30

We could call gpiod_to_irq() only if IS_ENABLED(CONFIG_GPIOLIB) but
without GPIOLIB, the driver's power saving features can't be used,
so selecting GPIOLIB seems more appropriate.

The same issue is present in hci_intel.c and hci_nokia.c, fix those up
as well.

Reported-by: Max Shavrick <mxms@me.com>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
---
 drivers/bluetooth/Kconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index 45a2f59cd935..41932f0e68d0 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -110,6 +110,7 @@ config BT_HCIUART_NOKIA
 	depends on PM
 	select BT_HCIUART_H4
 	select BT_BCM
+	select GPIOLIB
 	help
 	  Nokia H4+ is serial protocol for communication between Bluetooth
 	  device and host. This protocol is required for Bluetooth devices
@@ -170,6 +171,7 @@ config BT_HCIUART_INTEL
 	depends on BT_HCIUART
 	select BT_HCIUART_H4
 	select BT_INTEL
+	select GPIOLIB
 	help
 	  The Intel protocol support enables Bluetooth HCI over serial
 	  port interface for Intel Bluetooth controllers.
@@ -183,6 +185,7 @@ config BT_HCIUART_BCM
 	depends on (!ACPI || SERIAL_DEV_CTRL_TTYPORT)
 	select BT_HCIUART_H4
 	select BT_BCM
+	select GPIOLIB
 	help
 	  The Broadcom protocol support enables Bluetooth HCI over serial
 	  port interface for Broadcom Bluetooth controllers.
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 2/3] Bluetooth: hci_bcm: Streamline runtime PM code
  2017-12-26 15:07 [PATCH 1/3] Bluetooth: hci_bcm: Support Apple GPIO handling Lukas Wunner
  2017-12-26 15:07 ` [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB Lukas Wunner
@ 2017-12-26 15:07 ` Lukas Wunner
  2017-12-26 20:57   ` Marcel Holtmann
  2017-12-26 17:08   ` Lukas Wunner
  2017-12-26 20:50 ` Marcel Holtmann
  3 siblings, 1 reply; 27+ messages in thread
From: Lukas Wunner @ 2017-12-26 15:07 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg
  Cc: Mika Westerberg, Andy Shevchenko, Frederic Danis, Loic Poulain,
	Hans de Goede, Max Shavrick, Leif Liddy, Daniel Roschka,
	Ronald Tschalaer, Peter Y. Chuang, linux-bluetooth

This driver seeks to force the Bluetooth device on for the duration of
5 seconds when the Bluetooth device has woken the host and after a
complete packet has been received.  It does that by calling:

    pm_runtime_get();
    pm_runtime_mark_last_busy();
    pm_runtime_put_autosuspend();

The same can be achieved more succinctly with:

    pm_request_resume();

That's because after runtime resuming the device, rpm_resume() invokes
pm_runtime_mark_last_busy() followed by rpm_idle(), which will cause
the device to be suspended after expiration of the autosuspend_delay.

No functional change intended.

Cc: Frédéric Danis <frederic.danis.oss@gmail.com>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
---
 drivers/bluetooth/hci_bcm.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index a1e59fc4acbc..539ba1c8615c 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -251,9 +251,7 @@ static irqreturn_t bcm_host_wake(int irq, void *data)
 
 	bt_dev_dbg(bdev, "Host wake IRQ");
 
-	pm_runtime_get(bdev->dev);
-	pm_runtime_mark_last_busy(bdev->dev);
-	pm_runtime_put_autosuspend(bdev->dev);
+	pm_request_resume(bdev->dev);
 
 	return IRQ_HANDLED;
 }
@@ -580,11 +578,8 @@ static int bcm_recv(struct hci_uart *hu, const void *data, int count)
 	} else if (!bcm->rx_skb) {
 		/* Delay auto-suspend when receiving completed packet */
 		mutex_lock(&bcm_device_lock);
-		if (bcm->dev && bcm_device_exists(bcm->dev)) {
-			pm_runtime_get(bcm->dev->dev);
-			pm_runtime_mark_last_busy(bcm->dev->dev);
-			pm_runtime_put_autosuspend(bcm->dev->dev);
-		}
+		if (bcm->dev && bcm_device_exists(bcm->dev))
+			pm_request_resume(bcm->dev->dev);
 		mutex_unlock(&bcm_device_lock);
 	}
 
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 1/3] Bluetooth: hci_bcm: Support Apple GPIO handling
@ 2017-12-26 15:07 Lukas Wunner
  2017-12-26 15:07 ` [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB Lukas Wunner
                   ` (3 more replies)
  0 siblings, 4 replies; 27+ messages in thread
From: Lukas Wunner @ 2017-12-26 15:07 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg
  Cc: Mika Westerberg, Andy Shevchenko, Frederic Danis, Loic Poulain,
	Hans de Goede, Max Shavrick, Leif Liddy, Daniel Roschka,
	Ronald Tschalaer, Peter Y. Chuang, linux-bluetooth

Enable Bluetooth on the following Macs which provide custom ACPI methods
to toggle the GPIOs for device wakeup and shutdown instead of accessing
the pins directly:

    MacBook8,1     2015  12"
    MacBook9,1     2016  12"
    MacBook10,1    2017  12"
    MacBookPro13,1 2016  13"
    MacBookPro13,2 2016  13" with Touch Bar
    MacBookPro13,3 2016  15" with Touch Bar
    MacBookPro14,1 2017  13"
    MacBookPro14,2 2017  13" with Touch Bar
    MacBookPro14,3 2017  15" with Touch Bar

On the MacBook8,1 Bluetooth is muxed with a second device (a debug port
on the SSD) under the control of PCH GPIO 36.  Because serdev cannot
deal with multiple slaves yet, it is currently necessary to patch the
DSDT and remove the SSDC device.

The custom ACPI methods are called:

    BTLP (Low Power) takes one argument, toggles device wakeup GPIO
    BTPU (Power Up) tells SMC to drive shutdown GPIO high
    BTPD (Power Down) tells SMC to drive shutdown GPIO low
    BTRS (Reset) calls BTPD followed by BTPU
    BTRB unknown, not present on all MacBooks

Search for the BTLP, BTPU and BTPD methods on ->probe and cache them in
struct bcm_device if the machine is a Mac.

Additionally, set the init_speed based on a custom device property
provided by Apple in lieu of _CRS resources.  The Broadcom UART's speed
is fixed on Apple Macs:  Any attempt to change it results in Bluetooth
status code 0x0c and bcm_set_baudrate() thus always returns -EBUSY.
By setting only the init_speed and leaving oper_speed at zero, we can
achieve that the host UART's speed is adjusted but the Broadcom UART's
speed is left as is.

The host wakeup pin goes into the SMC which handles it independently
from the OS, so there's no IRQ for it.  The ->close, ->suspend and
->resume hooks assume presence of a valid IRQ if the device is wakeup
capable.  That's a problem on Macs where the ACPI core marks the device
wakeup capable due to presence of a _PRW method.  (It specifies the
SMC's GPE as wake event.)  Amend the three hooks to not fiddle with the
IRQ if it's invalid, i.e. <= 0.

Runtime PM is currently set up in bcm_request_irq() even though it's
independent of host wake.  Move the function calls related to runtime PM
to bcm_setup() so that they get executed even if setup of the IRQ is
skipped.

The existing code is a bit fishy as it ignores the return value of
bcm_gpio_set_power(), even though portions of it may fail (such as
enabling the clock).  The present commit returns an error if calling
the ACPI methods fails and the code needs to be fixed up in a separate
commit to evaluate the return value of bcm_gpio_set_power() and
bcm_gpio_set_device_wake(), as well as check for failure of clock
enablement and so on.

Thanks to Ronald Tschalär who did extensive debugging and testing of
this patch and contributed fixes.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=110901
Reported-by: Leif Liddy <leif.liddy@gmail.com>
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Frédéric Danis <frederic.danis.oss@gmail.com>
Cc: Loic Poulain <loic.poulain@linaro.org>
Cc: Hans de Goede <hdegoede@redhat.com>
Tested-by: Max Shavrick <mxms@me.com>                     [MacBook8,1]
Tested-by: Leif Liddy <leif.liddy@gmail.com>              [MacBook9,1]
Tested-by: Daniel Roschka <danielroschka@phoenitydawn.de> [MacBookPro13,2]
Tested-by: Ronald Tschalär <ronald@innovation.ch>        [MacBookPro13,3]
Tested-by: Peter Y. Chuang <peteryuchuang@gmail.com>      [MacBookPro14,1]
Signed-off-by: Ronald Tschalär <ronald@innovation.ch>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
---
 drivers/bluetooth/hci_bcm.c | 101 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 82 insertions(+), 19 deletions(-)

diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index 47fc58c9eb49..a1e59fc4acbc 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -29,6 +29,7 @@
 #include <linux/acpi.h>
 #include <linux/of.h>
 #include <linux/property.h>
+#include <linux/platform_data/x86/apple.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/gpio/consumer.h>
@@ -76,6 +77,9 @@ struct bcm_device {
 	struct hci_uart		*hu;
 	bool			is_suspended; /* suspend/resume flag */
 #endif
+#ifdef CONFIG_ACPI
+	acpi_handle		btlp, btpu, btpd;
+#endif
 };
 
 /* generic bcm uart resources */
@@ -168,8 +172,47 @@ static bool bcm_device_exists(struct bcm_device *device)
 	return false;
 }
 
+#ifdef CONFIG_ACPI
+static int bcm_apple_probe(struct bcm_device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev->dev);
+	acpi_handle dev_handle = adev->handle;
+	const union acpi_object *obj;
+
+	if (!acpi_dev_get_property(adev, "baud", ACPI_TYPE_BUFFER, &obj) &&
+	    obj->buffer.length == 8)
+		dev->init_speed = *(u64 *)obj->buffer.pointer;
+
+	return ACPI_SUCCESS(acpi_get_handle(dev_handle, "BTLP", &dev->btlp)) &&
+	       ACPI_SUCCESS(acpi_get_handle(dev_handle, "BTPU", &dev->btpu)) &&
+	       ACPI_SUCCESS(acpi_get_handle(dev_handle, "BTPD", &dev->btpd))
+								 ? 0 : -ENODEV;
+}
+
+static int bcm_apple_set_power(struct bcm_device *dev, bool enable)
+{
+	return ACPI_SUCCESS(acpi_evaluate_object(enable ? dev->btpu : dev->btpd,
+						 NULL, NULL, NULL))
+								 ? 0 : -EFAULT;
+}
+
+static int bcm_apple_set_low_power(struct bcm_device *dev, bool enable)
+{
+	return ACPI_SUCCESS(acpi_execute_simple_method(dev->btlp, NULL, enable))
+								 ? 0 : -EFAULT;
+}
+#else
+static inline int bcm_apple_set_power(struct bcm_device *dev, bool powered)
+{ return -EINVAL; }
+static inline int bcm_apple_set_low_power(struct bcm_device *dev, bool enable)
+{ return -EINVAL; }
+#endif
+
 static int bcm_gpio_set_power(struct bcm_device *dev, bool powered)
 {
+	if (x86_apple_machine)
+		return bcm_apple_set_power(dev, powered);
+
 	if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled)
 		clk_prepare_enable(dev->clk);
 
@@ -184,6 +227,23 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered)
 	return 0;
 }
 
+static int bcm_gpio_set_device_wake(struct bcm_device *dev, bool awake)
+{
+	int err = 0;
+
+	if (x86_apple_machine)
+		err = bcm_apple_set_low_power(dev, !awake);
+	else if (dev->device_wakeup)
+		gpiod_set_value(dev->device_wakeup, awake);
+	else
+		return 0;
+
+	bt_dev_dbg(dev, "%s, delaying 15 ms", awake ? "resume" : "suspend");
+	mdelay(15);
+
+	return err;
+}
+
 #ifdef CONFIG_PM
 static irqreturn_t bcm_host_wake(int irq, void *data)
 {
@@ -209,6 +269,15 @@ static int bcm_request_irq(struct bcm_data *bcm)
 		goto unlock;
 	}
 
+	/*
+	 * Macs wire the host wake pin to the System Management Controller,
+	 * which handles wakeup independently from the operating system.
+	 */
+	if (x86_apple_machine) {
+		err = 0;
+		goto unlock;
+	}
+
 	if (bdev->irq <= 0) {
 		err = -EOPNOTSUPP;
 		goto unlock;
@@ -223,12 +292,6 @@ static int bcm_request_irq(struct bcm_data *bcm)
 
 	device_init_wakeup(bdev->dev, true);
 
-	pm_runtime_set_autosuspend_delay(bdev->dev,
-					 BCM_AUTOSUSPEND_DELAY);
-	pm_runtime_use_autosuspend(bdev->dev);
-	pm_runtime_set_active(bdev->dev);
-	pm_runtime_enable(bdev->dev);
-
 unlock:
 	mutex_unlock(&bcm_device_lock);
 
@@ -379,7 +442,7 @@ static int bcm_close(struct hci_uart *hu)
 		pm_runtime_disable(bdev->dev);
 		pm_runtime_set_suspended(bdev->dev);
 
-		if (device_can_wakeup(bdev->dev)) {
+		if (bdev->irq > 0) {
 			devm_free_irq(bdev->dev, bdev->irq, bdev);
 			device_init_wakeup(bdev->dev, false);
 		}
@@ -470,6 +533,11 @@ static int bcm_setup(struct hci_uart *hu)
 	if (!bcm_request_irq(bcm))
 		err = bcm_setup_sleep(hu);
 
+	pm_runtime_set_autosuspend_delay(bcm->dev->dev, BCM_AUTOSUSPEND_DELAY);
+	pm_runtime_use_autosuspend(bcm->dev->dev);
+	pm_runtime_set_active(bcm->dev->dev);
+	pm_runtime_enable(bcm->dev->dev);
+
 	return err;
 }
 
@@ -577,11 +645,7 @@ static int bcm_suspend_device(struct device *dev)
 	}
 
 	/* Suspend the device */
-	if (bdev->device_wakeup) {
-		gpiod_set_value(bdev->device_wakeup, false);
-		bt_dev_dbg(bdev, "suspend, delaying 15 ms");
-		mdelay(15);
-	}
+	bcm_gpio_set_device_wake(bdev, false);
 
 	return 0;
 }
@@ -592,11 +656,7 @@ static int bcm_resume_device(struct device *dev)
 
 	bt_dev_dbg(bdev, "");
 
-	if (bdev->device_wakeup) {
-		gpiod_set_value(bdev->device_wakeup, true);
-		bt_dev_dbg(bdev, "resume, delaying 15 ms");
-		mdelay(15);
-	}
+	bcm_gpio_set_device_wake(bdev, true);
 
 	/* When this executes, the device has woken up already */
 	if (bdev->is_suspended && bdev->hu) {
@@ -632,7 +692,7 @@ static int bcm_suspend(struct device *dev)
 	if (pm_runtime_active(dev))
 		bcm_suspend_device(dev);
 
-	if (device_may_wakeup(dev)) {
+	if (device_may_wakeup(dev) && bdev->irq > 0) {
 		error = enable_irq_wake(bdev->irq);
 		if (!error)
 			bt_dev_dbg(bdev, "BCM irq: enabled");
@@ -662,7 +722,7 @@ static int bcm_resume(struct device *dev)
 	if (!bdev->hu)
 		goto unlock;
 
-	if (device_may_wakeup(dev)) {
+	if (device_may_wakeup(dev) && bdev->irq > 0) {
 		disable_irq_wake(bdev->irq);
 		bt_dev_dbg(bdev, "BCM irq: disabled");
 	}
@@ -816,6 +876,9 @@ static int bcm_acpi_probe(struct bcm_device *dev)
 	struct resource_entry *entry;
 	int ret;
 
+	if (x86_apple_machine)
+		return bcm_apple_probe(dev);
+
 	/* Retrieve GPIO data */
 	id = acpi_match_device(dev->dev->driver->acpi_match_table, dev->dev);
 	if (id)
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/3] Bluetooth: hci_bcm: Support Apple GPIO handling
@ 2017-12-26 17:08   ` Lukas Wunner
  0 siblings, 0 replies; 27+ messages in thread
From: Lukas Wunner @ 2017-12-26 17:08 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: Rob Herring, Peter Rosin, Johan Hovold, Marcel Holtmann,
	Johan Hedberg, Mika Westerberg, Andy Shevchenko, Frederic Danis,
	Loic Poulain, Hans de Goede, Max Shavrick, Leif Liddy,
	Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth, linux-serial

Hi Ulrich,

On Tue, Dec 26, 2017 at 05:07:34PM +0200, Lukas Wunner wrote:
> On the MacBook8,1 Bluetooth is muxed with a second device (a debug port
> on the SSD) under the control of PCH GPIO 36.  Because serdev cannot
> deal with multiple slaves yet, it is currently necessary to patch the
> DSDT and remove the SSDC device.

Last August you posted a series to add multiplexer support for serdev:

https://www.spinics.net/lists/linux-serial/msg27329.html

Another use case has now popped up where a GPIO-controlled mux is used
to switch between two serdev slaves:  As mentioned in a series I've just
posted to linux-bluetooth@ (quoted above), on the MacBook 8,1 the UART
is attached to a serial debug port on the SSD as well as to a Bluetooth
controller, subject to a mux controlled by PCH GPIO 36.

The SSD debug ported is listed first in the ACPI namespace and is attached
as a serdev slave without a hitch (see DSDT excerpt included below).
The Bluetooth controller comes next and fails to register due to a sanity
check in serdev_device_add():

[    0.361650] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[    0.362633] 0000:00:15.5: ttyS0 at MMIO 0xc1819000 (irq = 21, base_baud = 2764800) is a 16550A
[    0.362769] serial serial0-0: controller busy
[    0.362815] serial serial0-0: failure adding ACPI serdev device. status -16
[    0.362860] serial serial0: tty port ttyS0 registered

The series you've posted in August hasn't been merged.  Taking a closer
look at patch [2/6] (linked above), you've put the calls to lock and
unlock the mux in the slave, i.e. max9260.c.  This works because in your
use case, the UART is shared only by MAX9260 chips.  I think a more
generic solution is called for which puts the locking of the mux in the
serdev controller and makes it fully transparent to the slaves.

So whenever data is read or written to the UART's FIFO or whenever
the modem control lines are accessed, the mux needs to be locked to
the respective slave first.

The sanity check introduced by 08fcee289f34 to prevent registration
of multiple serdev slaves needs to be amended to check for presence
of a mux if more than one slave registers, and check whether the
number of switch states is sufficient to accomodate the additional
slave.

If you do find the time to amend the series in this way, it would
result in something truly useful that we could also employ to solve
Bluetooth muxing on the MacBook8,1 in a clean way.

Thanks,

Lukas

-- cut here --

            Device (URT0)
            {
                Name (_ADR, 0x00150005)  // _ADR: Address
                Name (RBUF, ResourceTemplate ()
                {
                    Interrupt (ResourceConsumer, Level, ActiveLow, Shared, ,, )
                    {
                        0x00000015,
                    }
                })
                Method (_STA, 0, NotSerialized)  // _STA: Status
                {
                    Return (0x0F)
                }

                Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
                {
                    If (LEqual (Arg0, ToUUID ("a0b5b7c6-1318-441c-b0c9-fe695eaf949b")))
                    {
                        Store (Package (0x02)
                            {
                                "uart-channel-number", 
                                Buffer (0x08)
                                {
                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                }
                            }, Local0)
                        DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
                        Return (Local0)
                    }

                    Return (0x00)
                }

                Name (DBUF, ResourceTemplate ()
                {
                    FixedDMA (0x0014, 0x0004, Width32bit, )
                    FixedDMA (0x0015, 0x0005, Width32bit, )
                })
                Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
                {
                    Return (ConcatenateResTemplate (RBUF, DBUF))
                }
            }

            Scope (\_SB.PCI0.URT0)
            {
                Device (SSDC)
                {
                    Name (_CID, "apple-uart-ssdc")  // _CID: Compatible ID
                    Name (_UID, 0x01)  // _UID: Unique ID
                    Name (_ADR, 0x00)  // _ADR: Address
                    Method (_STA, 0, NotSerialized)  // _STA: Status
                    {
                        Return (0x0F)
                    }

                    Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
                    {
                        If (LEqual (Arg0, ToUUID ("a0b5b7c6-1318-441c-b0c9-fe695eaf949b")))
                        {
                            Store (Package (0x08)
                                {
                                    "baud", 
                                    Buffer (0x08)
                                    {
                                         0xD0, 0x12, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                    }, 

                                    "parity", 
                                    Buffer (0x08)
                                    {
                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                    }, 

                                    "dataBits", 
                                    Buffer (0x08)
                                    {
                                         0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                    }, 

                                    "stopBits", 
                                    Buffer (0x08)
                                    {
                                         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                    }
                                }, Local0)
                            DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
                            Return (Local0)
                        }

                        Return (0x00)
                    }
                }
            }

            Scope (\_SB.PCI0.URT0)
            {
                Device (BLTH)
                {
                    Name (_HID, EisaId ("BCM2E7C"))  // _HID: Hardware ID
                    Name (_CID, "apple-uart-blth")  // _CID: Compatible ID
                    Name (_UID, 0x01)  // _UID: Unique ID
                    Name (_ADR, 0x00)  // _ADR: Address
                    Method (_STA, 0, NotSerialized)  // _STA: Status
                    {
                        Return (0x0F)
                    }

                    Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
                    {
                        Name (UBUF, ResourceTemplate ()
                        {
                            UartSerialBus (0x0001C200, DataBitsEight, StopBitsOne,
                                0xC0, LittleEndian, ParityTypeNone, FlowControlHardware,
                                0x0020, 0x0020, "\\_SB.PCI0.URT0",
                                0x00, ResourceProducer, ,
                                )
                        })
                        Name (ABUF, ResourceTemplate ()
                        {
                        })
                        If (LNot (OSDW ()))
                        {
                            Return (UBUF) /* \_SB_.PCI0.URT0.BLTH._CRS.UBUF */
                        }

                        Return (ABUF) /* \_SB_.PCI0.URT0.BLTH._CRS.ABUF */
                    }

                    Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
                    {
                        If (LEqual (Arg0, ToUUID ("a0b5b7c6-1318-441c-b0c9-fe695eaf949b")))
                        {
                            Store (Package (0x08)
                                {
                                    "baud", 
                                    Buffer (0x08)
                                    {
                                         0xC0, 0xC6, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00   /* ..-..... */
                                    }, 

                                    "parity", 
                                    Buffer (0x08)
                                    {
                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                    }, 

                                    "dataBits", 
                                    Buffer (0x08)
                                    {
                                         0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                    }, 

                                    "stopBits", 
                                    Buffer (0x08)
                                    {
                                         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                    }
                                }, Local0)
                            DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
                            Return (Local0)
                        }

                        Return (0x00)
                    }

                    Method (BTPU, 0, Serialized)
                    {
                        Store (0x01, \_SB.PCI0.LPCB.EC.BTPC)
                        Sleep (0x0A)
                    }

                    Method (BTPD, 0, Serialized)
                    {
                        Store (0x00, \_SB.PCI0.LPCB.EC.BTPC)
                        Sleep (0x0A)
                    }

                    Method (BTRS, 0, Serialized)
                    {
                        BTPD ()
                        BTPU ()
                    }

                    Method (BTLP, 1, Serialized)
                    {
                        If (LEqual (Arg0, 0x00))
                        {
                            Store (0x01, GD54) /* \GD54 */
                        }

                        If (LEqual (Arg0, 0x01))
                        {
                            Store (0x00, GD54) /* \GD54 */
                            Store (0x00, GP54) /* \GP54 */
                        }
                    }
                }
            }
        }

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/3] Bluetooth: hci_bcm: Support Apple GPIO handling
@ 2017-12-26 17:08   ` Lukas Wunner
  0 siblings, 0 replies; 27+ messages in thread
From: Lukas Wunner @ 2017-12-26 17:08 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: Rob Herring, Peter Rosin, Johan Hovold, Marcel Holtmann,
	Johan Hedberg, Mika Westerberg, Andy Shevchenko, Frederic Danis,
	Loic Poulain, Hans de Goede, Max Shavrick, Leif Liddy,
	Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth-u79uwXL29TY76Z2rM5mHXA,
	linux-serial-u79uwXL29TY76Z2rM5mHXA

Hi Ulrich,

On Tue, Dec 26, 2017 at 05:07:34PM +0200, Lukas Wunner wrote:
> On the MacBook8,1 Bluetooth is muxed with a second device (a debug port
> on the SSD) under the control of PCH GPIO 36.  Because serdev cannot
> deal with multiple slaves yet, it is currently necessary to patch the
> DSDT and remove the SSDC device.

Last August you posted a series to add multiplexer support for serdev:

https://www.spinics.net/lists/linux-serial/msg27329.html

Another use case has now popped up where a GPIO-controlled mux is used
to switch between two serdev slaves:  As mentioned in a series I've just
posted to linux-bluetooth@ (quoted above), on the MacBook 8,1 the UART
is attached to a serial debug port on the SSD as well as to a Bluetooth
controller, subject to a mux controlled by PCH GPIO 36.

The SSD debug ported is listed first in the ACPI namespace and is attached
as a serdev slave without a hitch (see DSDT excerpt included below).
The Bluetooth controller comes next and fails to register due to a sanity
check in serdev_device_add():

[    0.361650] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[    0.362633] 0000:00:15.5: ttyS0 at MMIO 0xc1819000 (irq = 21, base_baud = 2764800) is a 16550A
[    0.362769] serial serial0-0: controller busy
[    0.362815] serial serial0-0: failure adding ACPI serdev device. status -16
[    0.362860] serial serial0: tty port ttyS0 registered

The series you've posted in August hasn't been merged.  Taking a closer
look at patch [2/6] (linked above), you've put the calls to lock and
unlock the mux in the slave, i.e. max9260.c.  This works because in your
use case, the UART is shared only by MAX9260 chips.  I think a more
generic solution is called for which puts the locking of the mux in the
serdev controller and makes it fully transparent to the slaves.

So whenever data is read or written to the UART's FIFO or whenever
the modem control lines are accessed, the mux needs to be locked to
the respective slave first.

The sanity check introduced by 08fcee289f34 to prevent registration
of multiple serdev slaves needs to be amended to check for presence
of a mux if more than one slave registers, and check whether the
number of switch states is sufficient to accomodate the additional
slave.

If you do find the time to amend the series in this way, it would
result in something truly useful that we could also employ to solve
Bluetooth muxing on the MacBook8,1 in a clean way.

Thanks,

Lukas

-- cut here --

            Device (URT0)
            {
                Name (_ADR, 0x00150005)  // _ADR: Address
                Name (RBUF, ResourceTemplate ()
                {
                    Interrupt (ResourceConsumer, Level, ActiveLow, Shared, ,, )
                    {
                        0x00000015,
                    }
                })
                Method (_STA, 0, NotSerialized)  // _STA: Status
                {
                    Return (0x0F)
                }

                Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
                {
                    If (LEqual (Arg0, ToUUID ("a0b5b7c6-1318-441c-b0c9-fe695eaf949b")))
                    {
                        Store (Package (0x02)
                            {
                                "uart-channel-number", 
                                Buffer (0x08)
                                {
                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                }
                            }, Local0)
                        DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
                        Return (Local0)
                    }

                    Return (0x00)
                }

                Name (DBUF, ResourceTemplate ()
                {
                    FixedDMA (0x0014, 0x0004, Width32bit, )
                    FixedDMA (0x0015, 0x0005, Width32bit, )
                })
                Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
                {
                    Return (ConcatenateResTemplate (RBUF, DBUF))
                }
            }

            Scope (\_SB.PCI0.URT0)
            {
                Device (SSDC)
                {
                    Name (_CID, "apple-uart-ssdc")  // _CID: Compatible ID
                    Name (_UID, 0x01)  // _UID: Unique ID
                    Name (_ADR, 0x00)  // _ADR: Address
                    Method (_STA, 0, NotSerialized)  // _STA: Status
                    {
                        Return (0x0F)
                    }

                    Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
                    {
                        If (LEqual (Arg0, ToUUID ("a0b5b7c6-1318-441c-b0c9-fe695eaf949b")))
                        {
                            Store (Package (0x08)
                                {
                                    "baud", 
                                    Buffer (0x08)
                                    {
                                         0xD0, 0x12, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                    }, 

                                    "parity", 
                                    Buffer (0x08)
                                    {
                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                    }, 

                                    "dataBits", 
                                    Buffer (0x08)
                                    {
                                         0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                    }, 

                                    "stopBits", 
                                    Buffer (0x08)
                                    {
                                         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                    }
                                }, Local0)
                            DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
                            Return (Local0)
                        }

                        Return (0x00)
                    }
                }
            }

            Scope (\_SB.PCI0.URT0)
            {
                Device (BLTH)
                {
                    Name (_HID, EisaId ("BCM2E7C"))  // _HID: Hardware ID
                    Name (_CID, "apple-uart-blth")  // _CID: Compatible ID
                    Name (_UID, 0x01)  // _UID: Unique ID
                    Name (_ADR, 0x00)  // _ADR: Address
                    Method (_STA, 0, NotSerialized)  // _STA: Status
                    {
                        Return (0x0F)
                    }

                    Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
                    {
                        Name (UBUF, ResourceTemplate ()
                        {
                            UartSerialBus (0x0001C200, DataBitsEight, StopBitsOne,
                                0xC0, LittleEndian, ParityTypeNone, FlowControlHardware,
                                0x0020, 0x0020, "\\_SB.PCI0.URT0",
                                0x00, ResourceProducer, ,
                                )
                        })
                        Name (ABUF, ResourceTemplate ()
                        {
                        })
                        If (LNot (OSDW ()))
                        {
                            Return (UBUF) /* \_SB_.PCI0.URT0.BLTH._CRS.UBUF */
                        }

                        Return (ABUF) /* \_SB_.PCI0.URT0.BLTH._CRS.ABUF */
                    }

                    Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
                    {
                        If (LEqual (Arg0, ToUUID ("a0b5b7c6-1318-441c-b0c9-fe695eaf949b")))
                        {
                            Store (Package (0x08)
                                {
                                    "baud", 
                                    Buffer (0x08)
                                    {
                                         0xC0, 0xC6, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00   /* ..-..... */
                                    }, 

                                    "parity", 
                                    Buffer (0x08)
                                    {
                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                    }, 

                                    "dataBits", 
                                    Buffer (0x08)
                                    {
                                         0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                    }, 

                                    "stopBits", 
                                    Buffer (0x08)
                                    {
                                         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   /* ........ */
                                    }
                                }, Local0)
                            DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
                            Return (Local0)
                        }

                        Return (0x00)
                    }

                    Method (BTPU, 0, Serialized)
                    {
                        Store (0x01, \_SB.PCI0.LPCB.EC.BTPC)
                        Sleep (0x0A)
                    }

                    Method (BTPD, 0, Serialized)
                    {
                        Store (0x00, \_SB.PCI0.LPCB.EC.BTPC)
                        Sleep (0x0A)
                    }

                    Method (BTRS, 0, Serialized)
                    {
                        BTPD ()
                        BTPU ()
                    }

                    Method (BTLP, 1, Serialized)
                    {
                        If (LEqual (Arg0, 0x00))
                        {
                            Store (0x01, GD54) /* \GD54 */
                        }

                        If (LEqual (Arg0, 0x01))
                        {
                            Store (0x00, GD54) /* \GD54 */
                            Store (0x00, GP54) /* \GP54 */
                        }
                    }
                }
            }
        }

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/3] Bluetooth: hci_bcm: Support Apple GPIO handling
  2017-12-26 15:07 [PATCH 1/3] Bluetooth: hci_bcm: Support Apple GPIO handling Lukas Wunner
                   ` (2 preceding siblings ...)
  2017-12-26 17:08   ` Lukas Wunner
@ 2017-12-26 20:50 ` Marcel Holtmann
  2017-12-27 14:17   ` Lukas Wunner
                     ` (2 more replies)
  3 siblings, 3 replies; 27+ messages in thread
From: Marcel Holtmann @ 2017-12-26 20:50 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: Johan Hedberg, Mika Westerberg, Andy Shevchenko, Frederic Danis,
	Loic Poulain, Hans de Goede, Max Shavrick, Leif Liddy,
	Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth

Hi Lukas,

> Enable Bluetooth on the following Macs which provide custom ACPI methods
> to toggle the GPIOs for device wakeup and shutdown instead of accessing
> the pins directly:
> 
>    MacBook8,1     2015  12"
>    MacBook9,1     2016  12"
>    MacBook10,1    2017  12"
>    MacBookPro13,1 2016  13"
>    MacBookPro13,2 2016  13" with Touch Bar
>    MacBookPro13,3 2016  15" with Touch Bar
>    MacBookPro14,1 2017  13"
>    MacBookPro14,2 2017  13" with Touch Bar
>    MacBookPro14,3 2017  15" with Touch Bar
> 
> On the MacBook8,1 Bluetooth is muxed with a second device (a debug port
> on the SSD) under the control of PCH GPIO 36.  Because serdev cannot
> deal with multiple slaves yet, it is currently necessary to patch the
> DSDT and remove the SSDC device.
> 
> The custom ACPI methods are called:
> 
>    BTLP (Low Power) takes one argument, toggles device wakeup GPIO
>    BTPU (Power Up) tells SMC to drive shutdown GPIO high
>    BTPD (Power Down) tells SMC to drive shutdown GPIO low
>    BTRS (Reset) calls BTPD followed by BTPU
>    BTRB unknown, not present on all MacBooks
> 
> Search for the BTLP, BTPU and BTPD methods on ->probe and cache them in
> struct bcm_device if the machine is a Mac.
> 
> Additionally, set the init_speed based on a custom device property
> provided by Apple in lieu of _CRS resources.  The Broadcom UART's speed
> is fixed on Apple Macs:  Any attempt to change it results in Bluetooth
> status code 0x0c and bcm_set_baudrate() thus always returns -EBUSY.
> By setting only the init_speed and leaving oper_speed at zero, we can
> achieve that the host UART's speed is adjusted but the Broadcom UART's
> speed is left as is.

can we get a text version of the ACPI resources printout included in the commit messages. So that they are available to look up if anybody has question or new devices come along.

> 
> The host wakeup pin goes into the SMC which handles it independently
> from the OS, so there's no IRQ for it.  The ->close, ->suspend and
> ->resume hooks assume presence of a valid IRQ if the device is wakeup
> capable.  That's a problem on Macs where the ACPI core marks the device
> wakeup capable due to presence of a _PRW method.  (It specifies the
> SMC's GPE as wake event.)  Amend the three hooks to not fiddle with the
> IRQ if it's invalid, i.e. <= 0.
> 
> Runtime PM is currently set up in bcm_request_irq() even though it's
> independent of host wake.  Move the function calls related to runtime PM
> to bcm_setup() so that they get executed even if setup of the IRQ is
> skipped.
> 
> The existing code is a bit fishy as it ignores the return value of
> bcm_gpio_set_power(), even though portions of it may fail (such as
> enabling the clock).  The present commit returns an error if calling
> the ACPI methods fails and the code needs to be fixed up in a separate
> commit to evaluate the return value of bcm_gpio_set_power() and
> bcm_gpio_set_device_wake(), as well as check for failure of clock
> enablement and so on.
> 
> Thanks to Ronald Tschalär who did extensive debugging and testing of
> this patch and contributed fixes.
> 
> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=110901
> Reported-by: Leif Liddy <leif.liddy@gmail.com>
> Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Frédéric Danis <frederic.danis.oss@gmail.com>
> Cc: Loic Poulain <loic.poulain@linaro.org>
> Cc: Hans de Goede <hdegoede@redhat.com>
> Tested-by: Max Shavrick <mxms@me.com>                     [MacBook8,1]
> Tested-by: Leif Liddy <leif.liddy@gmail.com>              [MacBook9,1]
> Tested-by: Daniel Roschka <danielroschka@phoenitydawn.de> [MacBookPro13,2]
> Tested-by: Ronald Tschalär <ronald@innovation.ch>        [MacBookPro13,3]
> Tested-by: Peter Y. Chuang <peteryuchuang@gmail.com>      [MacBookPro14,1]
> Signed-off-by: Ronald Tschalär <ronald@innovation.ch>
> Signed-off-by: Lukas Wunner <lukas@wunner.de>
> ---
> drivers/bluetooth/hci_bcm.c | 101 +++++++++++++++++++++++++++++++++++---------
> 1 file changed, 82 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
> index 47fc58c9eb49..a1e59fc4acbc 100644
> --- a/drivers/bluetooth/hci_bcm.c
> +++ b/drivers/bluetooth/hci_bcm.c
> @@ -29,6 +29,7 @@
> #include <linux/acpi.h>
> #include <linux/of.h>
> #include <linux/property.h>
> +#include <linux/platform_data/x86/apple.h>
> #include <linux/platform_device.h>
> #include <linux/clk.h>
> #include <linux/gpio/consumer.h>
> @@ -76,6 +77,9 @@ struct bcm_device {
> 	struct hci_uart		*hu;
> 	bool			is_suspended; /* suspend/resume flag */
> #endif
> +#ifdef CONFIG_ACPI
> +	acpi_handle		btlp, btpu, btpd;
> +#endif
> };
> 
> /* generic bcm uart resources */
> @@ -168,8 +172,47 @@ static bool bcm_device_exists(struct bcm_device *device)
> 	return false;
> }
> 
> +#ifdef CONFIG_ACPI
> +static int bcm_apple_probe(struct bcm_device *dev)
> +{
> +	struct acpi_device *adev = ACPI_COMPANION(dev->dev);
> +	acpi_handle dev_handle = adev->handle;
> +	const union acpi_object *obj;
> +
> +	if (!acpi_dev_get_property(adev, "baud", ACPI_TYPE_BUFFER, &obj) &&
> +	    obj->buffer.length == 8)
> +		dev->init_speed = *(u64 *)obj->buffer.pointer;

	if (!ACPI_SUCCESS(..))
		return -ENODEV;

	..

	return 0;

> +
> +	return ACPI_SUCCESS(acpi_get_handle(dev_handle, "BTLP", &dev->btlp)) &&
> +	       ACPI_SUCCESS(acpi_get_handle(dev_handle, "BTPU", &dev->btpu)) &&
> +	       ACPI_SUCCESS(acpi_get_handle(dev_handle, "BTPD", &dev->btpd))
> +								 ? 0 : -ENODEV;

I wonder if the above reads easier than just doing it line by line. We have enough lines to use, but squeezing it all in with a ? : operator seems not easy to read.

> +}
> +
> +static int bcm_apple_set_power(struct bcm_device *dev, bool enable)
> +{
> +	return ACPI_SUCCESS(acpi_evaluate_object(enable ? dev->btpu : dev->btpd,
> +						 NULL, NULL, NULL))
> +								 ? 0 : -EFAULT;

Same here. Trying to mush everything in a single statement seems overkill. And btw. why -EFAULT? Is that standard error practice with ACPI?

> +}
> +
> +static int bcm_apple_set_low_power(struct bcm_device *dev, bool enable)
> +{
> +	return ACPI_SUCCESS(acpi_execute_simple_method(dev->btlp, NULL, enable))
> +								 ? 0 : -EFAULT;
> +}
> +#else
> +static inline int bcm_apple_set_power(struct bcm_device *dev, bool powered)
> +{ return -EINVAL; }
> +static inline int bcm_apple_set_low_power(struct bcm_device *dev, bool enable)
> +{ return -EINVAL; }
> +#endif

Not -EOPNOTSUPP here. At least that is what we are doing within the btbcm.h. I just like to hear an opinion on why -EINVAL.

> +
> static int bcm_gpio_set_power(struct bcm_device *dev, bool powered)
> {
> +	if (x86_apple_machine)
> +		return bcm_apple_set_power(dev, powered);
> +
> 	if (powered && !IS_ERR(dev->clk) && !dev->clk_enabled)
> 		clk_prepare_enable(dev->clk);
> 
> @@ -184,6 +227,23 @@ static int bcm_gpio_set_power(struct bcm_device *dev, bool powered)
> 	return 0;
> }
> 
> +static int bcm_gpio_set_device_wake(struct bcm_device *dev, bool awake)
> +{
> +	int err = 0;
> +
> +	if (x86_apple_machine)
> +		err = bcm_apple_set_low_power(dev, !awake);
> +	else if (dev->device_wakeup)
> +		gpiod_set_value(dev->device_wakeup, awake);
> +	else
> +		return 0;
> +
> +	bt_dev_dbg(dev, "%s, delaying 15 ms", awake ? "resume" : "suspend");
> +	mdelay(15);

Any chance for a comment here on why a delay of 15ms is needed?

> +
> +	return err;
> +}
> +
> #ifdef CONFIG_PM
> static irqreturn_t bcm_host_wake(int irq, void *data)
> {
> @@ -209,6 +269,15 @@ static int bcm_request_irq(struct bcm_data *bcm)
> 		goto unlock;
> 	}
> 
> +	/*
> +	 * Macs wire the host wake pin to the System Management Controller,
> +	 * which handles wakeup independently from the operating system.
> +	 */

Network subsystem comment style please.

> +	if (x86_apple_machine) {
> +		err = 0;
> +		goto unlock;
> +	}
> +
> 	if (bdev->irq <= 0) {
> 		err = -EOPNOTSUPP;
> 		goto unlock;
> @@ -223,12 +292,6 @@ static int bcm_request_irq(struct bcm_data *bcm)
> 
> 	device_init_wakeup(bdev->dev, true);
> 
> -	pm_runtime_set_autosuspend_delay(bdev->dev,
> -					 BCM_AUTOSUSPEND_DELAY);
> -	pm_runtime_use_autosuspend(bdev->dev);
> -	pm_runtime_set_active(bdev->dev);
> -	pm_runtime_enable(bdev->dev);
> -
> unlock:
> 	mutex_unlock(&bcm_device_lock);
> 
> @@ -379,7 +442,7 @@ static int bcm_close(struct hci_uart *hu)
> 		pm_runtime_disable(bdev->dev);
> 		pm_runtime_set_suspended(bdev->dev);
> 
> -		if (device_can_wakeup(bdev->dev)) {
> +		if (bdev->irq > 0) {
> 			devm_free_irq(bdev->dev, bdev->irq, bdev);
> 			device_init_wakeup(bdev->dev, false);
> 		}
> @@ -470,6 +533,11 @@ static int bcm_setup(struct hci_uart *hu)
> 	if (!bcm_request_irq(bcm))
> 		err = bcm_setup_sleep(hu);
> 
> +	pm_runtime_set_autosuspend_delay(bcm->dev->dev, BCM_AUTOSUSPEND_DELAY);
> +	pm_runtime_use_autosuspend(bcm->dev->dev);
> +	pm_runtime_set_active(bcm->dev->dev);
> +	pm_runtime_enable(bcm->dev->dev);
> +

Is this block really part of this patch or should it be done as a pre-patch with the other patch you have?

> 	return err;
> }
> 
> @@ -577,11 +645,7 @@ static int bcm_suspend_device(struct device *dev)
> 	}
> 
> 	/* Suspend the device */
> -	if (bdev->device_wakeup) {
> -		gpiod_set_value(bdev->device_wakeup, false);
> -		bt_dev_dbg(bdev, "suspend, delaying 15 ms");
> -		mdelay(15);
> -	}
> +	bcm_gpio_set_device_wake(bdev, false);

Seems unrelated and can be done in an initial cleanup patch?

> 
> 	return 0;
> }
> @@ -592,11 +656,7 @@ static int bcm_resume_device(struct device *dev)
> 
> 	bt_dev_dbg(bdev, "");
> 
> -	if (bdev->device_wakeup) {
> -		gpiod_set_value(bdev->device_wakeup, true);
> -		bt_dev_dbg(bdev, "resume, delaying 15 ms");
> -		mdelay(15);
> -	}
> +	bcm_gpio_set_device_wake(bdev, true);

Same as above.

> 
> 	/* When this executes, the device has woken up already */
> 	if (bdev->is_suspended && bdev->hu) {
> @@ -632,7 +692,7 @@ static int bcm_suspend(struct device *dev)
> 	if (pm_runtime_active(dev))
> 		bcm_suspend_device(dev);
> 
> -	if (device_may_wakeup(dev)) {
> +	if (device_may_wakeup(dev) && bdev->irq > 0) {
> 		error = enable_irq_wake(bdev->irq);
> 		if (!error)
> 			bt_dev_dbg(bdev, "BCM irq: enabled");
> @@ -662,7 +722,7 @@ static int bcm_resume(struct device *dev)
> 	if (!bdev->hu)
> 		goto unlock;
> 
> -	if (device_may_wakeup(dev)) {
> +	if (device_may_wakeup(dev) && bdev->irq > 0) {
> 		disable_irq_wake(bdev->irq);
> 		bt_dev_dbg(bdev, "BCM irq: disabled");
> 	}
> @@ -816,6 +876,9 @@ static int bcm_acpi_probe(struct bcm_device *dev)
> 	struct resource_entry *entry;
> 	int ret;
> 
> +	if (x86_apple_machine)
> +		return bcm_apple_probe(dev);
> +
> 	/* Retrieve GPIO data */
> 	id = acpi_match_device(dev->dev->driver->acpi_match_table, dev->dev);
> 	if (id)

Regards

Marcel


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 2/3] Bluetooth: hci_bcm: Streamline runtime PM code
  2017-12-26 15:07 ` [PATCH 2/3] Bluetooth: hci_bcm: Streamline runtime PM code Lukas Wunner
@ 2017-12-26 20:57   ` Marcel Holtmann
  0 siblings, 0 replies; 27+ messages in thread
From: Marcel Holtmann @ 2017-12-26 20:57 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: Johan Hedberg, Mika Westerberg, Andy Shevchenko, Frederic Danis,
	Loic Poulain, Hans de Goede, Max Shavrick, Leif Liddy,
	Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth

Hi Lukas,

> This driver seeks to force the Bluetooth device on for the duration of
> 5 seconds when the Bluetooth device has woken the host and after a
> complete packet has been received.  It does that by calling:
> 
>    pm_runtime_get();
>    pm_runtime_mark_last_busy();
>    pm_runtime_put_autosuspend();
> 
> The same can be achieved more succinctly with:
> 
>    pm_request_resume();
> 
> That's because after runtime resuming the device, rpm_resume() invokes
> pm_runtime_mark_last_busy() followed by rpm_idle(), which will cause
> the device to be suspended after expiration of the autosuspend_delay.
> 
> No functional change intended.
> 
> Cc: Frédéric Danis <frederic.danis.oss@gmail.com>
> Signed-off-by: Lukas Wunner <lukas@wunner.de>
> ---
> drivers/bluetooth/hci_bcm.c | 11 +++--------
> 1 file changed, 3 insertions(+), 8 deletions(-)

patch has been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2017-12-26 15:07 ` [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB Lukas Wunner
@ 2017-12-26 20:57   ` Marcel Holtmann
  2017-12-28  8:41   ` Andy Shevchenko
  1 sibling, 0 replies; 27+ messages in thread
From: Marcel Holtmann @ 2017-12-26 20:57 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: Johan Hedberg, Mika Westerberg, Andy Shevchenko, Frederic Danis,
	Loic Poulain, Hans de Goede, Max Shavrick, Leif Liddy,
	Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth

Hi Lukas,

> Loading hci_bcm with CONFIG_GPIOLIB=n results in the following splat
> when calling gpiod_to_irq() from bcm_get_resources():
> 
>    WARNING: CPU: 0 PID: 1006 at ./include/linux/gpio/consumer.h:450 bcm_get_resources+0x50/0x80
>    CPU: 0 PID: 1006 Comm: kworker/u8:4 Tainted: G       A         4.15.0-rc4custom+ #4
>    Hardware name: Apple Inc. MacBook8,1/Mac-BE0E8AC46FE800CC, BIOS MB81.88Z.0168.B00.1708080033 08/08/2017
>    Call Trace:
>    bcm_serdev_probe+0x8b/0xc0
>    driver_probe_device+0x202/0x310
>    __driver_attach+0x85/0x90
>    ? driver_probe_device+0x310/0x310
>    bus_for_each_dev+0x57/0x80
>    async_run_entry_fn+0x2c/0xd0
>    process_one_work+0x1d2/0x3d0
>    worker_thread+0x26/0x3c0
>    ? process_one_work+0x3d0/0x3d0
>    kthread+0x10c/0x130
>    ? kthread_create_on_node+0x40/0x40
>    ret_from_fork+0x1f/0x30
> 
> We could call gpiod_to_irq() only if IS_ENABLED(CONFIG_GPIOLIB) but
> without GPIOLIB, the driver's power saving features can't be used,
> so selecting GPIOLIB seems more appropriate.
> 
> The same issue is present in hci_intel.c and hci_nokia.c, fix those up
> as well.
> 
> Reported-by: Max Shavrick <mxms@me.com>
> Signed-off-by: Lukas Wunner <lukas@wunner.de>
> ---
> drivers/bluetooth/Kconfig | 3 +++
> 1 file changed, 3 insertions(+)

patch has been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/3] Bluetooth: hci_bcm: Support Apple GPIO handling
  2017-12-26 20:50 ` Marcel Holtmann
@ 2017-12-27 14:17   ` Lukas Wunner
  2017-12-28  7:15   ` Lukas Wunner
  2017-12-28  7:38   ` Andy Shevchenko
  2 siblings, 0 replies; 27+ messages in thread
From: Lukas Wunner @ 2017-12-27 14:17 UTC (permalink / raw)
  To: Frederic Danis
  Cc: Marcel Holtmann, Johan Hedberg, Mika Westerberg, Andy Shevchenko,
	Loic Poulain, Hans de Goede, Max Shavrick, Leif Liddy,
	Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth

Hi Frederic,

On Tue, Dec 26, 2017 at 09:50:30PM +0100, Marcel Holtmann wrote:
> > +static int bcm_gpio_set_device_wake(struct bcm_device *dev, bool awake)
> > +{
> > +	int err = 0;
> > +
> > +	if (x86_apple_machine)
> > +		err = bcm_apple_set_low_power(dev, !awake);
> > +	else if (dev->device_wakeup)
> > +		gpiod_set_value(dev->device_wakeup, awake);
> > +	else
> > +		return 0;
> > +
> > +	bt_dev_dbg(dev, "%s, delaying 15 ms", awake ? "resume" : "suspend");
> > +	mdelay(15);
> 
> Any chance for a comment here on why a delay of 15ms is needed?

The delay was introduced by your commit 118612fb9165 ("Bluetooth:
hci_bcm: Add suspend/resume PM functions").

Could you provide a rationale for it?  Perhaps 15 ms is the time
after which the controller auto-suspends following deassertion of
the device wake pin (which forces it into "on" state AFAIUI)?

Is there public documentation on this controller? I've tried to
search for it but my google-fu is failing me.

Thanks,

Lukas

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/3] Bluetooth: hci_bcm: Support Apple GPIO handling
  2017-12-26 20:50 ` Marcel Holtmann
  2017-12-27 14:17   ` Lukas Wunner
@ 2017-12-28  7:15   ` Lukas Wunner
  2017-12-28 12:40     ` Hans de Goede
  2017-12-28  7:38   ` Andy Shevchenko
  2 siblings, 1 reply; 27+ messages in thread
From: Lukas Wunner @ 2017-12-28  7:15 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Johan Hedberg, Mika Westerberg, Andy Shevchenko, Frederic Danis,
	Loic Poulain, Hans de Goede, Max Shavrick, Leif Liddy,
	Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth

On Tue, Dec 26, 2017 at 09:50:30PM +0100, Marcel Holtmann wrote:
> > +}
> > +
> > +static int bcm_apple_set_power(struct bcm_device *dev, bool enable)
> > +{
> > +	return ACPI_SUCCESS(acpi_evaluate_object(enable ? dev->btpu : dev->btpd,
> > +						 NULL, NULL, NULL))
> > +								 ? 0 : -EFAULT;
> 
> Same here. Trying to mush everything in a single statement seems overkill.
> And btw. why -EFAULT? Is that standard error practice with ACPI?

-EFAULT was just chosen as a generic error because we don't really know
what went wrong with the ACPI call.  It seems there's no function to
convert an ACPI exception code to an errno, only a function to convert it
to a human-readable string, acpi_format_exception().  If you have a
different preference than -EFAULT I'd be happy to change it.

D'accord on all your other comments, will respin in the coming days.

Thanks,

Lukas

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/3] Bluetooth: hci_bcm: Support Apple GPIO handling
  2017-12-26 20:50 ` Marcel Holtmann
  2017-12-27 14:17   ` Lukas Wunner
  2017-12-28  7:15   ` Lukas Wunner
@ 2017-12-28  7:38   ` Andy Shevchenko
  2 siblings, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2017-12-28  7:38 UTC (permalink / raw)
  To: Marcel Holtmann, Lukas Wunner
  Cc: Johan Hedberg, Mika Westerberg, Frederic Danis, Loic Poulain,
	Hans de Goede, Max Shavrick, Leif Liddy, Daniel Roschka,
	Ronald Tschalaer, Peter Y. Chuang, linux-bluetooth

On Tue, 2017-12-26 at 21:50 +0100, Marcel Holtmann wrote:
> Hi Lukas,
> 
> > 

> > +
> > +	if (!acpi_dev_get_property(adev, "baud", ACPI_TYPE_BUFFER,
> > &obj) &&
> > +	    obj->buffer.length == 8)
> > +		dev->init_speed = *(u64 *)obj->buffer.pointer;
> 
> 	if (!ACPI_SUCCESS(..))
> 		return -ENODEV;

ACPI_FAILURE()

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2017-12-26 15:07 ` [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB Lukas Wunner
  2017-12-26 20:57   ` Marcel Holtmann
@ 2017-12-28  8:41   ` Andy Shevchenko
  2017-12-28  9:18     ` Lukas Wunner
  1 sibling, 1 reply; 27+ messages in thread
From: Andy Shevchenko @ 2017-12-28  8:41 UTC (permalink / raw)
  To: Lukas Wunner, Marcel Holtmann, Johan Hedberg, Linus Walleij
  Cc: Mika Westerberg, Frederic Danis, Loic Poulain, Hans de Goede,
	Max Shavrick, Leif Liddy, Daniel Roschka, Ronald Tschalaer,
	Peter Y. Chuang, linux-bluetooth

On Tue, 2017-12-26 at 17:07 +0200, Lukas Wunner wrote:
> Loading hci_bcm with CONFIG_GPIOLIB=n results in the following splat
> when calling gpiod_to_irq() from bcm_get_resources():
> 
>     WARNING: CPU: 0 PID: 1006 at ./include/linux/gpio/consumer.h:450
> bcm_get_resources+0x50/0x80
>     CPU: 0 PID: 1006 Comm: kworker/u8:4 Tainted:
> G       A         4.15.0-rc4custom+ #4
>     Hardware name: Apple Inc. MacBook8,1/Mac-BE0E8AC46FE800CC, BIOS
> MB81.88Z.0168.B00.1708080033 08/08/2017
>     Call Trace:
>     bcm_serdev_probe+0x8b/0xc0
>     driver_probe_device+0x202/0x310
>     __driver_attach+0x85/0x90
>     ? driver_probe_device+0x310/0x310
>     bus_for_each_dev+0x57/0x80
>     async_run_entry_fn+0x2c/0xd0
>     process_one_work+0x1d2/0x3d0
>     worker_thread+0x26/0x3c0
>     ? process_one_work+0x3d0/0x3d0
>     kthread+0x10c/0x130
>     ? kthread_create_on_node+0x40/0x40
>     ret_from_fork+0x1f/0x30
> 
> We could call gpiod_to_irq() only if IS_ENABLED(CONFIG_GPIOLIB) but
> without GPIOLIB, the driver's power saving features can't be used,
> so selecting GPIOLIB seems more appropriate.
> 
> The same issue is present in hci_intel.c and hci_nokia.c, fix those up
> as well.
> 
> Reported-by: Max Shavrick <mxms@me.com>
> Signed-off-by: Lukas Wunner <lukas@wunner.de>
> ---
>  drivers/bluetooth/Kconfig | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
> index 45a2f59cd935..41932f0e68d0 100644
> --- a/drivers/bluetooth/Kconfig
> +++ b/drivers/bluetooth/Kconfig
> @@ -110,6 +110,7 @@ config BT_HCIUART_NOKIA
>  	depends on PM
>  	select BT_HCIUART_H4
>  	select BT_BCM
> +	select GPIOLIB

This is wrong solution. GPIOLIB is meant for GPIO providers, not
consumers.

That's why after I did BT support for Intel MID (commit d4d96990)
the necessity of exporting gpiod_add_lookup_table() had been arisen
(commit 020e0b1c8f19f).

+Cc Linus W

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2017-12-28  8:41   ` Andy Shevchenko
@ 2017-12-28  9:18     ` Lukas Wunner
  2017-12-28  9:26       ` Andy Shevchenko
  0 siblings, 1 reply; 27+ messages in thread
From: Lukas Wunner @ 2017-12-28  9:18 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Marcel Holtmann, Johan Hedberg, Linus Walleij, Mika Westerberg,
	Frederic Danis, Loic Poulain, Hans de Goede, Max Shavrick,
	Leif Liddy, Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth

On Thu, Dec 28, 2017 at 10:41:17AM +0200, Andy Shevchenko wrote:
> On Tue, 2017-12-26 at 17:07 +0200, Lukas Wunner wrote:
> > Loading hci_bcm with CONFIG_GPIOLIB=n results in the following splat
> > when calling gpiod_to_irq() from bcm_get_resources():
> > 
> >     WARNING: CPU: 0 PID: 1006 at ./include/linux/gpio/consumer.h:450
> > bcm_get_resources+0x50/0x80
> >     CPU: 0 PID: 1006 Comm: kworker/u8:4 Tainted:
> > G       A         4.15.0-rc4custom+ #4
> >     Hardware name: Apple Inc. MacBook8,1/Mac-BE0E8AC46FE800CC, BIOS
> > MB81.88Z.0168.B00.1708080033 08/08/2017
> >     Call Trace:
> >     bcm_serdev_probe+0x8b/0xc0
> >     driver_probe_device+0x202/0x310
> >     __driver_attach+0x85/0x90
> >     ? driver_probe_device+0x310/0x310
> >     bus_for_each_dev+0x57/0x80
> >     async_run_entry_fn+0x2c/0xd0
> >     process_one_work+0x1d2/0x3d0
> >     worker_thread+0x26/0x3c0
> >     ? process_one_work+0x3d0/0x3d0
> >     kthread+0x10c/0x130
> >     ? kthread_create_on_node+0x40/0x40
> >     ret_from_fork+0x1f/0x30
> > 
> > We could call gpiod_to_irq() only if IS_ENABLED(CONFIG_GPIOLIB) but
> > without GPIOLIB, the driver's power saving features can't be used,
> > so selecting GPIOLIB seems more appropriate.
> > 
> > The same issue is present in hci_intel.c and hci_nokia.c, fix those up
> > as well.
> > 
> > Reported-by: Max Shavrick <mxms@me.com>
> > Signed-off-by: Lukas Wunner <lukas@wunner.de>
> > ---
> >  drivers/bluetooth/Kconfig | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
> > index 45a2f59cd935..41932f0e68d0 100644
> > --- a/drivers/bluetooth/Kconfig
> > +++ b/drivers/bluetooth/Kconfig
> > @@ -110,6 +110,7 @@ config BT_HCIUART_NOKIA
> >  	depends on PM
> >  	select BT_HCIUART_H4
> >  	select BT_BCM
> > +	select GPIOLIB
> 
> This is wrong solution. GPIOLIB is meant for GPIO providers, not
> consumers.
> 
> That's why after I did BT support for Intel MID (commit d4d96990)
> the necessity of exporting gpiod_add_lookup_table() had been arisen
> (commit 020e0b1c8f19f).

Hm okay, Documentation/gpio/consumer.txt says:

    Guidelines for GPIOs consumers
    ==============================

    Drivers that can't work without standard GPIO calls should have
    Kconfig entries that depend on GPIOLIB.

So a "depends on GPIOLIB" would be more appropriate, right?

Thanks,

Lukas

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2017-12-28  9:18     ` Lukas Wunner
@ 2017-12-28  9:26       ` Andy Shevchenko
  2017-12-28 12:29         ` Linus Walleij
  0 siblings, 1 reply; 27+ messages in thread
From: Andy Shevchenko @ 2017-12-28  9:26 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: Marcel Holtmann, Johan Hedberg, Linus Walleij, Mika Westerberg,
	Frederic Danis, Loic Poulain, Hans de Goede, Max Shavrick,
	Leif Liddy, Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth

On Thu, 2017-12-28 at 10:18 +0100, Lukas Wunner wrote:
> On Thu, Dec 28, 2017 at 10:41:17AM +0200, Andy Shevchenko wrote:
> > On Tue, 2017-12-26 at 17:07 +0200, Lukas Wunner wrote:
> > > Loading hci_bcm with CONFIG_GPIOLIB=n results in the following
> > > splat
> > > when calling gpiod_to_irq() from bcm_get_resources():
> > > 
> > >     WARNING: CPU: 0 PID: 1006 at
> > > ./include/linux/gpio/consumer.h:450
> > > bcm_get_resources+0x50/0x80
> > >     CPU: 0 PID: 1006 Comm: kworker/u8:4 Tainted:
> > > G       A         4.15.0-rc4custom+ #4
> > >     Hardware name: Apple Inc. MacBook8,1/Mac-BE0E8AC46FE800CC,
> > > BIOS
> > > MB81.88Z.0168.B00.1708080033 08/08/2017
> > >     Call Trace:
> > >     bcm_serdev_probe+0x8b/0xc0
> > >     driver_probe_device+0x202/0x310
> > >     __driver_attach+0x85/0x90
> > >     ? driver_probe_device+0x310/0x310
> > >     bus_for_each_dev+0x57/0x80
> > >     async_run_entry_fn+0x2c/0xd0
> > >     process_one_work+0x1d2/0x3d0
> > >     worker_thread+0x26/0x3c0
> > >     ? process_one_work+0x3d0/0x3d0
> > >     kthread+0x10c/0x130
> > >     ? kthread_create_on_node+0x40/0x40
> > >     ret_from_fork+0x1f/0x30
> > > 
> > > We could call gpiod_to_irq() only if IS_ENABLED(CONFIG_GPIOLIB)
> > > but
> > > without GPIOLIB, the driver's power saving features can't be used,
> > > so selecting GPIOLIB seems more appropriate.
> > > 
> > > The same issue is present in hci_intel.c and hci_nokia.c, fix
> > > those up
> > > as well.
> > > 

> > > +	select GPIOLIB
> > 
> > This is wrong solution. GPIOLIB is meant for GPIO providers, not
> > consumers.
> > 
> > That's why after I did BT support for Intel MID (commit d4d96990)
> > the necessity of exporting gpiod_add_lookup_table() had been arisen
> > (commit 020e0b1c8f19f).
> 
> Hm okay, Documentation/gpio/consumer.txt says:
> 
>     Guidelines for GPIOs consumers
>     ==============================
> 
>     Drivers that can't work without standard GPIO calls should have
>     Kconfig entries that depend on GPIOLIB.
> 
> So a "depends on GPIOLIB" would be more appropriate, right?

Yes, but still wrong for this certain driver. It *can* work w/o GPIOLIB.
Now you have done unnecessary dependency for that case.

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2017-12-28  9:26       ` Andy Shevchenko
@ 2017-12-28 12:29         ` Linus Walleij
  2017-12-28 12:40           ` Andy Shevchenko
  0 siblings, 1 reply; 27+ messages in thread
From: Linus Walleij @ 2017-12-28 12:29 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Lukas Wunner, Marcel Holtmann, Johan Hedberg, Mika Westerberg,
	Frederic Danis, Loic Poulain, Hans de Goede, Max Shavrick,
	Leif Liddy, Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth

On Thu, Dec 28, 2017 at 10:26 AM, Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
> On Thu, 2017-12-28 at 10:18 +0100, Lukas Wunner wrote:
>> On Thu, Dec 28, 2017 at 10:41:17AM +0200, Andy Shevchenko wrote:
>> > On Tue, 2017-12-26 at 17:07 +0200, Lukas Wunner wrote:
>> > > Loading hci_bcm with CONFIG_GPIOLIB=n results in the following
>> > > splat
>> > > when calling gpiod_to_irq() from bcm_get_resources():
>> > >
>> > >     WARNING: CPU: 0 PID: 1006 at
>> > > ./include/linux/gpio/consumer.h:450
>> > > bcm_get_resources+0x50/0x80
>> > >     CPU: 0 PID: 1006 Comm: kworker/u8:4 Tainted:
>> > > G       A         4.15.0-rc4custom+ #4
>> > >     Hardware name: Apple Inc. MacBook8,1/Mac-BE0E8AC46FE800CC,
>> > > BIOS
>> > > MB81.88Z.0168.B00.1708080033 08/08/2017
>> > >     Call Trace:
>> > >     bcm_serdev_probe+0x8b/0xc0
>> > >     driver_probe_device+0x202/0x310
>> > >     __driver_attach+0x85/0x90
>> > >     ? driver_probe_device+0x310/0x310
>> > >     bus_for_each_dev+0x57/0x80
>> > >     async_run_entry_fn+0x2c/0xd0
>> > >     process_one_work+0x1d2/0x3d0
>> > >     worker_thread+0x26/0x3c0
>> > >     ? process_one_work+0x3d0/0x3d0
>> > >     kthread+0x10c/0x130
>> > >     ? kthread_create_on_node+0x40/0x40
>> > >     ret_from_fork+0x1f/0x30
>> > >
>> > > We could call gpiod_to_irq() only if IS_ENABLED(CONFIG_GPIOLIB)
>> > > but
>> > > without GPIOLIB, the driver's power saving features can't be used,
>> > > so selecting GPIOLIB seems more appropriate.
>> > >
>> > > The same issue is present in hci_intel.c and hci_nokia.c, fix
>> > > those up
>> > > as well.
>> > >
>
>> > > + select GPIOLIB
>> >
>> > This is wrong solution. GPIOLIB is meant for GPIO providers, not
>> > consumers.
>> >
>> > That's why after I did BT support for Intel MID (commit d4d96990)
>> > the necessity of exporting gpiod_add_lookup_table() had been arisen
>> > (commit 020e0b1c8f19f).
>>
>> Hm okay, Documentation/gpio/consumer.txt says:
>>
>>     Guidelines for GPIOs consumers
>>     ==============================
>>
>>     Drivers that can't work without standard GPIO calls should have
>>     Kconfig entries that depend on GPIOLIB.
>>
>> So a "depends on GPIOLIB" would be more appropriate, right?
>
> Yes, but still wrong for this certain driver. It *can* work w/o GPIOLIB.
> Now you have done unnecessary dependency for that case.

No I think it should use depends on GPIOLIB.

The reason is that the driver uses unconditional devm_gpiod_get(),
not devm_gpiod_get_optional().

The only thing you achieve if you do not have a GPIOLIB is a driver
that always exits probe with an error.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/3] Bluetooth: hci_bcm: Support Apple GPIO handling
  2017-12-28  7:15   ` Lukas Wunner
@ 2017-12-28 12:40     ` Hans de Goede
  0 siblings, 0 replies; 27+ messages in thread
From: Hans de Goede @ 2017-12-28 12:40 UTC (permalink / raw)
  To: Lukas Wunner, Marcel Holtmann
  Cc: Johan Hedberg, Mika Westerberg, Andy Shevchenko, Frederic Danis,
	Loic Poulain, Max Shavrick, Leif Liddy, Daniel Roschka,
	Ronald Tschalaer, Peter Y. Chuang, linux-bluetooth

Hi,

On 28-12-17 08:15, Lukas Wunner wrote:
> On Tue, Dec 26, 2017 at 09:50:30PM +0100, Marcel Holtmann wrote:
>>> +}
>>> +
>>> +static int bcm_apple_set_power(struct bcm_device *dev, bool enable)
>>> +{
>>> +	return ACPI_SUCCESS(acpi_evaluate_object(enable ? dev->btpu : dev->btpd,
>>> +						 NULL, NULL, NULL))
>>> +								 ? 0 : -EFAULT;
>>
>> Same here. Trying to mush everything in a single statement seems overkill.
>> And btw. why -EFAULT? Is that standard error practice with ACPI?
> 
> -EFAULT was just chosen as a generic error because we don't really know
> what went wrong with the ACPI call.  It seems there's no function to
> convert an ACPI exception code to an errno, only a function to convert it
> to a human-readable string, acpi_format_exception().  If you have a
> different preference than -EFAULT I'd be happy to change it.

In that case please use e.g. -EIO, or something else similar, EFAULT
has a very clear definition: userspace has called us with an invalid
address (which would cause a segfault when used from userspace code
directly), so please do not use it for anything else.

Regards,

Hans

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2017-12-28 12:29         ` Linus Walleij
@ 2017-12-28 12:40           ` Andy Shevchenko
  2017-12-28 12:45             ` Linus Walleij
  0 siblings, 1 reply; 27+ messages in thread
From: Andy Shevchenko @ 2017-12-28 12:40 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Lukas Wunner, Marcel Holtmann, Johan Hedberg, Mika Westerberg,
	Frederic Danis, Loic Poulain, Hans de Goede, Max Shavrick,
	Leif Liddy, Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth

On Thu, 2017-12-28 at 13:29 +0100, Linus Walleij wrote:
> On Thu, Dec 28, 2017 at 10:26 AM, Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> > On Thu, 2017-12-28 at 10:18 +0100, Lukas Wunner wrote:
> > > On Thu, Dec 28, 2017 at 10:41:17AM +0200, Andy Shevchenko wrote:
> > > > On Tue, 2017-12-26 at 17:07 +0200, Lukas Wunner wrote:

> > > Hm okay, Documentation/gpio/consumer.txt says:
> > > 
> > >     Guidelines for GPIOs consumers
> > >     ==============================
> > > 
> > >     Drivers that can't work without standard GPIO calls should
> > > have
> > >     Kconfig entries that depend on GPIOLIB.
> > > 
> > > So a "depends on GPIOLIB" would be more appropriate, right?
> > 
> > Yes, but still wrong for this certain driver. It *can* work w/o
> > GPIOLIB.
> > Now you have done unnecessary dependency for that case.
> 
> No I think it should use depends on GPIOLIB.
> 
> The reason is that the driver uses unconditional devm_gpiod_get(),
> not devm_gpiod_get_optional().

How come?
I just checked the code, all three use _optional() variant.

I checked in bcm_get_resources().

> 
> The only thing you achieve if you do not have a GPIOLIB is a driver
> that always exits probe with an error.

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2017-12-28 12:40           ` Andy Shevchenko
@ 2017-12-28 12:45             ` Linus Walleij
  2017-12-29  9:51               ` Lukas Wunner
  0 siblings, 1 reply; 27+ messages in thread
From: Linus Walleij @ 2017-12-28 12:45 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Lukas Wunner, Marcel Holtmann, Johan Hedberg, Mika Westerberg,
	Frederic Danis, Loic Poulain, Hans de Goede, Max Shavrick,
	Leif Liddy, Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth

On Thu, Dec 28, 2017 at 1:40 PM, Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
> On Thu, 2017-12-28 at 13:29 +0100, Linus Walleij wrote:
>> On Thu, Dec 28, 2017 at 10:26 AM, Andy Shevchenko
>> <andriy.shevchenko@linux.intel.com> wrote:
>> > On Thu, 2017-12-28 at 10:18 +0100, Lukas Wunner wrote:
>> > > On Thu, Dec 28, 2017 at 10:41:17AM +0200, Andy Shevchenko wrote:
>> > > > On Tue, 2017-12-26 at 17:07 +0200, Lukas Wunner wrote:
>
>> > > Hm okay, Documentation/gpio/consumer.txt says:
>> > >
>> > >     Guidelines for GPIOs consumers
>> > >     ==============================
>> > >
>> > >     Drivers that can't work without standard GPIO calls should
>> > > have
>> > >     Kconfig entries that depend on GPIOLIB.
>> > >
>> > > So a "depends on GPIOLIB" would be more appropriate, right?
>> >
>> > Yes, but still wrong for this certain driver. It *can* work w/o
>> > GPIOLIB.
>> > Now you have done unnecessary dependency for that case.
>>
>> No I think it should use depends on GPIOLIB.
>>
>> The reason is that the driver uses unconditional devm_gpiod_get(),
>> not devm_gpiod_get_optional().
>
> How come?
> I just checked the code, all three use _optional() variant.
>
> I checked in bcm_get_resources().

I'm as confused as you are :D

The patch says:

> Loading hci_bcm with CONFIG_GPIOLIB=n results in the following splat
> when calling gpiod_to_irq() from bcm_get_resources():

Which leads to bcm and it is correct as you state it, but it patches:

> diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
> index 45a2f59cd935..41932f0e68d0 100644
> --- a/drivers/bluetooth/Kconfig
> +++ b/drivers/bluetooth/Kconfig
> @@ -110,6 +110,7 @@ config BT_HCIUART_NOKIA
>       depends on PM
>       select BT_HCIUART_H4
>       select BT_BCM
> +     select GPIOLIB

And BT_HCIUART_NOKIA compiles drivers/bluetooth/hci_nokia.c
which does depend on GPIOLIB.

Apart from selectng BT_BCM.

So I suspect the descripton and/or patch is wrong...

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2017-12-28 12:45             ` Linus Walleij
@ 2017-12-29  9:51               ` Lukas Wunner
  2017-12-29 14:18                 ` Loic Poulain
  2018-01-01 15:23                 ` Linus Walleij
  0 siblings, 2 replies; 27+ messages in thread
From: Lukas Wunner @ 2017-12-29  9:51 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Andy Shevchenko, Marcel Holtmann, Johan Hedberg, Mika Westerberg,
	Frederic Danis, Loic Poulain, Hans de Goede, Max Shavrick,
	Leif Liddy, Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth

On Thu, Dec 28, 2017 at 01:45:34PM +0100, Linus Walleij wrote:
> On Thu, Dec 28, 2017 at 1:40 PM, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> > On Thu, 2017-12-28 at 13:29 +0100, Linus Walleij wrote:
> >> On Thu, Dec 28, 2017 at 10:26 AM, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> >> > On Thu, 2017-12-28 at 10:18 +0100, Lukas Wunner wrote:
> >> > > On Thu, Dec 28, 2017 at 10:41:17AM +0200, Andy Shevchenko wrote:
> >> > > > On Tue, 2017-12-26 at 17:07 +0200, Lukas Wunner wrote:
> >> > > Hm okay, Documentation/gpio/consumer.txt says:
> >> > >
> >> > >     Guidelines for GPIOs consumers
> >> > >     ==============================
> >> > >
> >> > >     Drivers that can't work without standard GPIO calls should have
> >> > >     Kconfig entries that depend on GPIOLIB.
> >> > >
> >> > > So a "depends on GPIOLIB" would be more appropriate, right?
> >> >
> >> > Yes, but still wrong for this certain driver. It *can* work w/o
> >> > GPIOLIB.
> >> > Now you have done unnecessary dependency for that case.
> >>
> >> No I think it should use depends on GPIOLIB.
> >>
> >> The reason is that the driver uses unconditional devm_gpiod_get(),
> >> not devm_gpiod_get_optional().
> >
> > How come?
> > I just checked the code, all three use _optional() variant.
> >
> > I checked in bcm_get_resources().

Even though hci_bcm.c uses devm_gpiod_get_optional() for the device
wakeup and shutdown pins, it calls gpiod_set_value() on both pins
without checking if the're NULL in bcm_gpio_set_power().

It also calls gpiod_to_irq() on the host wakeup pin without checking
if it's NULL in bcm_get_resources(), which results in a WARN splat
if GPIOLIB is not enabled.

So this is clearly wrong.  The problem is, I don't have this hardware
to test myself, I don't have a spec for the chip and I don't know
what the driver author's intention was.  Perhaps these are just glitches
that snuck in when power management was retrofitted into the driver
and we can fix them with a few NULL pointer checks.  But I'm not sure
if these pins are really optional.  What if there are boards where
the chip is off by default and must be powered on by the driver?
In that case the pins aren't optional and enabling GPIOLIB is required.

I guess this driver was never really tested without these pins present
as users would immediately get a NULL pointer deref on probe.


> And BT_HCIUART_NOKIA compiles drivers/bluetooth/hci_nokia.c
> which does depend on GPIOLIB.

Sorry, you weren't cc'ed on the original patch, I stated in the commit
message:

    The same issue is present in hci_intel.c and hci_nokia.c, fix those up
    as well.

These two use devm_gpiod_get(), so we agree that they need to depend
on GPIOLIB, right?

By the way, what is the rationale for this rule that consumers shall
depend on rather than select GPIOLIB?  So that users are forced to
enable at least one GPIO driver?  If that is the motivation, it's
not bullet-proof as users can still select GPIOLIB without selecting
a driver, or select an input-only GPIO driver even though the GPIOs
are used as outputs by hci_*.c.

Thanks,

Lukas

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2017-12-29  9:51               ` Lukas Wunner
@ 2017-12-29 14:18                 ` Loic Poulain
  2017-12-29 15:12                   ` Lukas Wunner
  2018-01-01 15:23                 ` Linus Walleij
  1 sibling, 1 reply; 27+ messages in thread
From: Loic Poulain @ 2017-12-29 14:18 UTC (permalink / raw)
  To: Lukas Wunner, Frédéric Danis
  Cc: Linus Walleij, Andy Shevchenko, Marcel Holtmann, Johan Hedberg,
	Mika Westerberg, Hans de Goede, Max Shavrick, Leif Liddy,
	Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	open list:BLUETOOTH DRIVERS

On 29 December 2017 at 10:51, Lukas Wunner <lukas@wunner.de> wrote:
> On Thu, Dec 28, 2017 at 01:45:34PM +0100, Linus Walleij wrote:
>> On Thu, Dec 28, 2017 at 1:40 PM, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
>> > On Thu, 2017-12-28 at 13:29 +0100, Linus Walleij wrote:
>> >> On Thu, Dec 28, 2017 at 10:26 AM, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
>> >> > On Thu, 2017-12-28 at 10:18 +0100, Lukas Wunner wrote:
>> >> > > On Thu, Dec 28, 2017 at 10:41:17AM +0200, Andy Shevchenko wrote:
>> >> > > > On Tue, 2017-12-26 at 17:07 +0200, Lukas Wunner wrote:
>> >> > > Hm okay, Documentation/gpio/consumer.txt says:
>> >> > >
>> >> > >     Guidelines for GPIOs consumers
>> >> > >     ==============================
>> >> > >
>> >> > >     Drivers that can't work without standard GPIO calls should have
>> >> > >     Kconfig entries that depend on GPIOLIB.
>> >> > >
>> >> > > So a "depends on GPIOLIB" would be more appropriate, right?
>> >> >
>> >> > Yes, but still wrong for this certain driver. It *can* work w/o
>> >> > GPIOLIB.
>> >> > Now you have done unnecessary dependency for that case.
>> >>
>> >> No I think it should use depends on GPIOLIB.
>> >>
>> >> The reason is that the driver uses unconditional devm_gpiod_get(),
>> >> not devm_gpiod_get_optional().
>> >
>> > How come?
>> > I just checked the code, all three use _optional() variant.
>> >
>> > I checked in bcm_get_resources().
>
> Even though hci_bcm.c uses devm_gpiod_get_optional() for the device
> wakeup and shutdown pins, it calls gpiod_set_value() on both pins
> without checking if the're NULL in bcm_gpio_set_power().
>
> It also calls gpiod_to_irq() on the host wakeup pin without checking
> if it's NULL in bcm_get_resources(), which results in a WARN splat
> if GPIOLIB is not enabled.
>
> So this is clearly wrong.  The problem is, I don't have this hardware
> to test myself, I don't have a spec for the chip and I don't know
> what the driver author's intention was.  Perhaps these are just glitches
> that snuck in when power management was retrofitted into the driver
> and we can fix them with a few NULL pointer checks.  But I'm not sure
> if these pins are really optional.

I think this is due to the adaptation to serdev bus support, originally a
platform device was only added to describe power control resources
(via ACPI/DT), there was no associated pdev for non 'gpio-controllable'
devices and so no gpio action. Now that serdev is supported I agree
that some pointer checks should be added.

Regards,
Loic

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2017-12-29 14:18                 ` Loic Poulain
@ 2017-12-29 15:12                   ` Lukas Wunner
  2017-12-29 15:18                     ` Andy Shevchenko
  2017-12-29 15:28                     ` Lukas Wunner
  0 siblings, 2 replies; 27+ messages in thread
From: Lukas Wunner @ 2017-12-29 15:12 UTC (permalink / raw)
  To: Loic Poulain
  Cc: Frédéric Danis, Linus Walleij, Andy Shevchenko,
	Marcel Holtmann, Johan Hedberg, Mika Westerberg, Hans de Goede,
	Max Shavrick, Leif Liddy, Daniel Roschka, Ronald Tschalaer,
	Peter Y. Chuang, open list:BLUETOOTH DRIVERS

On Fri, Dec 29, 2017 at 03:18:44PM +0100, Loic Poulain wrote:
> On 29 December 2017 at 10:51, Lukas Wunner <lukas@wunner.de> wrote:
> > On Thu, Dec 28, 2017 at 01:45:34PM +0100, Linus Walleij wrote:
> >> On Thu, Dec 28, 2017 at 1:40 PM, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> >> > On Thu, 2017-12-28 at 13:29 +0100, Linus Walleij wrote:
> >> >> On Thu, Dec 28, 2017 at 10:26 AM, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> >> >> > On Thu, 2017-12-28 at 10:18 +0100, Lukas Wunner wrote:
> >> >> > > On Thu, Dec 28, 2017 at 10:41:17AM +0200, Andy Shevchenko wrote:
> >> >> > > > On Tue, 2017-12-26 at 17:07 +0200, Lukas Wunner wrote:
> >> >> > > Hm okay, Documentation/gpio/consumer.txt says:
> >> >> > >
> >> >> > >     Guidelines for GPIOs consumers
> >> >> > >     ==============================
> >> >> > >
> >> >> > >     Drivers that can't work without standard GPIO calls should have
> >> >> > >     Kconfig entries that depend on GPIOLIB.
> >> >> > >
> >> >> > > So a "depends on GPIOLIB" would be more appropriate, right?
> >> >> >
> >> >> > Yes, but still wrong for this certain driver. It *can* work w/o
> >> >> > GPIOLIB.
> >> >> > Now you have done unnecessary dependency for that case.
> >> >>
> >> >> No I think it should use depends on GPIOLIB.
> >> >>
> >> >> The reason is that the driver uses unconditional devm_gpiod_get(),
> >> >> not devm_gpiod_get_optional().
> >> >
> >> > How come?
> >> > I just checked the code, all three use _optional() variant.
> >> >
> >> > I checked in bcm_get_resources().
> >
> > Even though hci_bcm.c uses devm_gpiod_get_optional() for the device
> > wakeup and shutdown pins, it calls gpiod_set_value() on both pins
> > without checking if the're NULL in bcm_gpio_set_power().
> >
> > It also calls gpiod_to_irq() on the host wakeup pin without checking
> > if it's NULL in bcm_get_resources(), which results in a WARN splat
> > if GPIOLIB is not enabled.
> >
> > So this is clearly wrong.  The problem is, I don't have this hardware
> > to test myself, I don't have a spec for the chip and I don't know
> > what the driver author's intention was.  Perhaps these are just glitches
> > that snuck in when power management was retrofitted into the driver
> > and we can fix them with a few NULL pointer checks.  But I'm not sure
> > if these pins are really optional.
> 
> I think this is due to the adaptation to serdev bus support, originally a
> platform device was only added to describe power control resources
> (via ACPI/DT), there was no associated pdev for non 'gpio-controllable'
> devices and so no gpio action. Now that serdev is supported I agree
> that some pointer checks should be added.

You're correct that GPIO use was originally mandatory in this driver,
but serdev has nothing to do with it becoming optional.

Rather, commit 62aaefa7d038 ("Bluetooth: hci_bcm: improve use of gpios
API") added the _optional "to simplify error handling".

So the _optional is a red herring and GPIO use is not optional at all
in this driver.  Adding Uwe Kleine-König to cc.

Thanks,

Lukas

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2017-12-29 15:12                   ` Lukas Wunner
@ 2017-12-29 15:18                     ` Andy Shevchenko
  2017-12-29 15:28                     ` Lukas Wunner
  1 sibling, 0 replies; 27+ messages in thread
From: Andy Shevchenko @ 2017-12-29 15:18 UTC (permalink / raw)
  To: Lukas Wunner, Loic Poulain
  Cc: Frédéric Danis, Linus Walleij, Marcel Holtmann,
	Johan Hedberg, Mika Westerberg, Hans de Goede, Max Shavrick,
	Leif Liddy, Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	open list:BLUETOOTH DRIVERS

On Fri, 2017-12-29 at 16:12 +0100, Lukas Wunner wrote:
> On Fri, Dec 29, 2017 at 03:18:44PM +0100, Loic Poulain wrote:
> > On 29 December 2017 at 10:51, Lukas Wunner <lukas@wunner.de> wrote:

> > I think this is due to the adaptation to serdev bus support,
> > originally a
> > platform device was only added to describe power control resources
> > (via ACPI/DT), there was no associated pdev for non 'gpio-
> > controllable'
> > devices and so no gpio action. Now that serdev is supported I agree
> > that some pointer checks should be added.
> 
> You're correct that GPIO use was originally mandatory in this driver,
> but serdev has nothing to do with it becoming optional.
> 
> Rather, commit 62aaefa7d038 ("Bluetooth: hci_bcm: improve use of gpios
> API") added the _optional "to simplify error handling".
> 
> So the _optional is a red herring and GPIO use is not optional at all
> in this driver.  Adding Uwe Kleine-König to cc.

I was about to propose to get rid of _optional there and thus depends on
GPIOLIB should work fine for !GPIOLIB case, right?

Otherwise GPIO library should be fixed to be transparent for !GPIOLIB
cases.

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2017-12-29 15:12                   ` Lukas Wunner
  2017-12-29 15:18                     ` Andy Shevchenko
@ 2017-12-29 15:28                     ` Lukas Wunner
  1 sibling, 0 replies; 27+ messages in thread
From: Lukas Wunner @ 2017-12-29 15:28 UTC (permalink / raw)
  To: Loic Poulain
  Cc: Frédéric Danis, Linus Walleij, Andy Shevchenko,
	Marcel Holtmann, Johan Hedberg, Mika Westerberg, Hans de Goede,
	Max Shavrick, Leif Liddy, Daniel Roschka, Ronald Tschalaer,
	Peter Y. Chuang, open list:BLUETOOTH DRIVERS,
	Uwe Kleine-König

On Fri, Dec 29, 2017 at 04:12:41PM +0100, Lukas Wunner wrote:
> On Fri, Dec 29, 2017 at 03:18:44PM +0100, Loic Poulain wrote:
> > On 29 December 2017 at 10:51, Lukas Wunner <lukas@wunner.de> wrote:
> > > On Thu, Dec 28, 2017 at 01:45:34PM +0100, Linus Walleij wrote:
> > >> On Thu, Dec 28, 2017 at 1:40 PM, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> > >> > On Thu, 2017-12-28 at 13:29 +0100, Linus Walleij wrote:
> > >> >> On Thu, Dec 28, 2017 at 10:26 AM, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> > >> >> > On Thu, 2017-12-28 at 10:18 +0100, Lukas Wunner wrote:
> > >> >> > > On Thu, Dec 28, 2017 at 10:41:17AM +0200, Andy Shevchenko wrote:
> > >> >> > > > On Tue, 2017-12-26 at 17:07 +0200, Lukas Wunner wrote:
> > >> >> > > Hm okay, Documentation/gpio/consumer.txt says:
> > >> >> > >
> > >> >> > >     Guidelines for GPIOs consumers
> > >> >> > >     ==============================
> > >> >> > >
> > >> >> > >     Drivers that can't work without standard GPIO calls should have
> > >> >> > >     Kconfig entries that depend on GPIOLIB.
> > >> >> > >
> > >> >> > > So a "depends on GPIOLIB" would be more appropriate, right?
> > >> >> >
> > >> >> > Yes, but still wrong for this certain driver. It *can* work w/o
> > >> >> > GPIOLIB.
> > >> >> > Now you have done unnecessary dependency for that case.
> > >> >>
> > >> >> No I think it should use depends on GPIOLIB.
> > >> >>
> > >> >> The reason is that the driver uses unconditional devm_gpiod_get(),
> > >> >> not devm_gpiod_get_optional().
> > >> >
> > >> > How come?
> > >> > I just checked the code, all three use _optional() variant.
> > >> >
> > >> > I checked in bcm_get_resources().
> > >
> > > Even though hci_bcm.c uses devm_gpiod_get_optional() for the device
> > > wakeup and shutdown pins, it calls gpiod_set_value() on both pins
> > > without checking if the're NULL in bcm_gpio_set_power().
> > >
> > > It also calls gpiod_to_irq() on the host wakeup pin without checking
> > > if it's NULL in bcm_get_resources(), which results in a WARN splat
> > > if GPIOLIB is not enabled.
> > >
> > > So this is clearly wrong.  The problem is, I don't have this hardware
> > > to test myself, I don't have a spec for the chip and I don't know
> > > what the driver author's intention was.  Perhaps these are just glitches
> > > that snuck in when power management was retrofitted into the driver
> > > and we can fix them with a few NULL pointer checks.  But I'm not sure
> > > if these pins are really optional.
> > 
> > I think this is due to the adaptation to serdev bus support, originally a
> > platform device was only added to describe power control resources
> > (via ACPI/DT), there was no associated pdev for non 'gpio-controllable'
> > devices and so no gpio action. Now that serdev is supported I agree
> > that some pointer checks should be added.
> 
> You're correct that GPIO use was originally mandatory in this driver,
> but serdev has nothing to do with it becoming optional.
> 
> Rather, commit 62aaefa7d038 ("Bluetooth: hci_bcm: improve use of gpios
> API") added the _optional "to simplify error handling".
> 
> So the _optional is a red herring and GPIO use is not optional at all
> in this driver.  Adding Uwe Kleine-König to cc.

Oh I guess you mean this part:

	/* Make sure at-least one of the GPIO is defined and that
	 * a name is specified for this instance
	 */
	if ((!dev->device_wakeup && !dev->shutdown) || !dev->name) {
		dev_err(dev->dev, "invalid platform data\n");
		return -EINVAL;
	}

Indeed this was removed by Hans with 8a92056837fd ("Bluetooth: hci_bcm:
Add (runtime)pm support to the serdev driver").

Hans, was this intentional?

BTW why was only one of the two pins required to be non-NULL?  Since
*both* pins are unconditionally accessed in bcm_gpio_set_power(),
which is called from the ->probe hook, we'd still get a NULL pointer
deref.  And this has been present ever since power management was
introduced with 0395ffc1ee05 ("Bluetooth: hci_bcm: Add PM for BCM
devices").

Adding Uwe to cc for real now, sorry.

Thanks,

Lukas

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2017-12-29  9:51               ` Lukas Wunner
  2017-12-29 14:18                 ` Loic Poulain
@ 2018-01-01 15:23                 ` Linus Walleij
  2018-01-02 15:27                   ` Marcel Holtmann
  1 sibling, 1 reply; 27+ messages in thread
From: Linus Walleij @ 2018-01-01 15:23 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: Andy Shevchenko, Marcel Holtmann, Johan Hedberg, Mika Westerberg,
	Frederic Danis, Loic Poulain, Hans de Goede, Max Shavrick,
	Leif Liddy, Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth

On Fri, Dec 29, 2017 at 10:51 AM, Lukas Wunner <lukas@wunner.de> wrote:

> By the way, what is the rationale for this rule that consumers shall
> depend on rather than select GPIOLIB?

I think consumers should depend on GPIOLIB and producers
should select GPIOLIB.

Alas, I suck at Kconfig, people have expressed that it is terse,
ambigous (to the point of not using regular grammar) and so
on, I am just as confused as the next developer.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2018-01-01 15:23                 ` Linus Walleij
@ 2018-01-02 15:27                   ` Marcel Holtmann
  2018-01-02 16:58                     ` Lukas Wunner
  0 siblings, 1 reply; 27+ messages in thread
From: Marcel Holtmann @ 2018-01-02 15:27 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Lukas Wunner, Andy Shevchenko, Johan Hedberg, Mika Westerberg,
	Frederic Danis, Loic Poulain, Hans de Goede, Max Shavrick,
	Leif Liddy, Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth

Hi Linus,

>> By the way, what is the rationale for this rule that consumers shall
>> depend on rather than select GPIOLIB?
> 
> I think consumers should depend on GPIOLIB and producers
> should select GPIOLIB.
> 
> Alas, I suck at Kconfig, people have expressed that it is terse,
> ambigous (to the point of not using regular grammar) and so
> on, I am just as confused as the next developer.

so what do we do here? Should I revert the patch or can I get an updated patch that uses the agreed upon select vs depends.

Regards

Marcel


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2018-01-02 15:27                   ` Marcel Holtmann
@ 2018-01-02 16:58                     ` Lukas Wunner
  2018-01-02 17:10                       ` Marcel Holtmann
  0 siblings, 1 reply; 27+ messages in thread
From: Lukas Wunner @ 2018-01-02 16:58 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Linus Walleij, Andy Shevchenko, Johan Hedberg, Mika Westerberg,
	Frederic Danis, Loic Poulain, Hans de Goede, Max Shavrick,
	Leif Liddy, Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth

On Tue, Jan 02, 2018 at 04:27:02PM +0100, Marcel Holtmann wrote:
> >> By the way, what is the rationale for this rule that consumers shall
> >> depend on rather than select GPIOLIB?
> > 
> > I think consumers should depend on GPIOLIB and producers
> > should select GPIOLIB.
> 
> so what do we do here? Should I revert the patch or can I get an updated
> patch that uses the agreed upon select vs depends.

I've prepared this branch which still needs to be tested & debugged,
it contains a patch to change the "select" to a "depends on":

https://github.com/l1k/linux/commits/hci_bcm_v2/
https://github.com/l1k/linux/commit/71aa06c610d0

If you prefer reverting 27378f4c1b92 or rebase your branch and drop it,
I'll be happy to provide a rectified version instead (basically
27378f4c1b92 and 71aa06c610d0 squashed together).  I was assuming that
bluetooth-next/master is a non-rebasing branch, hence prepared
71aa06c610d0 as a fix of the existing commit.

Thanks,

Lukas

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB
  2018-01-02 16:58                     ` Lukas Wunner
@ 2018-01-02 17:10                       ` Marcel Holtmann
  0 siblings, 0 replies; 27+ messages in thread
From: Marcel Holtmann @ 2018-01-02 17:10 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: Linus Walleij, Andy Shevchenko, Johan Hedberg, Mika Westerberg,
	Frederic Danis, Loic Poulain, Hans de Goede, Max Shavrick,
	Leif Liddy, Daniel Roschka, Ronald Tschalaer, Peter Y. Chuang,
	linux-bluetooth

Hi Lukas,

>>>> By the way, what is the rationale for this rule that consumers shall
>>>> depend on rather than select GPIOLIB?
>>> 
>>> I think consumers should depend on GPIOLIB and producers
>>> should select GPIOLIB.
>> 
>> so what do we do here? Should I revert the patch or can I get an updated
>> patch that uses the agreed upon select vs depends.
> 
> I've prepared this branch which still needs to be tested & debugged,
> it contains a patch to change the "select" to a "depends on":
> 
> https://github.com/l1k/linux/commits/hci_bcm_v2/
> https://github.com/l1k/linux/commit/71aa06c610d0
> 
> If you prefer reverting 27378f4c1b92 or rebase your branch and drop it,
> I'll be happy to provide a rectified version instead (basically
> 27378f4c1b92 and 71aa06c610d0 squashed together).  I was assuming that
> bluetooth-next/master is a non-rebasing branch, hence prepared
> 71aa06c610d0 as a fix of the existing commit.

I will revert and rebase if I have to, but if we can just get a fix applied on top of it, then that works for me as well.

Regards

Marcel


^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2018-01-02 17:10 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-26 15:07 [PATCH 1/3] Bluetooth: hci_bcm: Support Apple GPIO handling Lukas Wunner
2017-12-26 15:07 ` [PATCH 3/3] Bluetooth: Avoid WARN splat due to missing GPIOLIB Lukas Wunner
2017-12-26 20:57   ` Marcel Holtmann
2017-12-28  8:41   ` Andy Shevchenko
2017-12-28  9:18     ` Lukas Wunner
2017-12-28  9:26       ` Andy Shevchenko
2017-12-28 12:29         ` Linus Walleij
2017-12-28 12:40           ` Andy Shevchenko
2017-12-28 12:45             ` Linus Walleij
2017-12-29  9:51               ` Lukas Wunner
2017-12-29 14:18                 ` Loic Poulain
2017-12-29 15:12                   ` Lukas Wunner
2017-12-29 15:18                     ` Andy Shevchenko
2017-12-29 15:28                     ` Lukas Wunner
2018-01-01 15:23                 ` Linus Walleij
2018-01-02 15:27                   ` Marcel Holtmann
2018-01-02 16:58                     ` Lukas Wunner
2018-01-02 17:10                       ` Marcel Holtmann
2017-12-26 15:07 ` [PATCH 2/3] Bluetooth: hci_bcm: Streamline runtime PM code Lukas Wunner
2017-12-26 20:57   ` Marcel Holtmann
2017-12-26 17:08 ` [PATCH 1/3] Bluetooth: hci_bcm: Support Apple GPIO handling Lukas Wunner
2017-12-26 17:08   ` Lukas Wunner
2017-12-26 20:50 ` Marcel Holtmann
2017-12-27 14:17   ` Lukas Wunner
2017-12-28  7:15   ` Lukas Wunner
2017-12-28 12:40     ` Hans de Goede
2017-12-28  7:38   ` Andy Shevchenko

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.