linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] platform/x86: GPD pocket fan: Set speed to max on get_temp failure
@ 2018-01-19 20:47 Hans de Goede
  2018-01-19 20:47 ` [PATCH 2/3] platform/x86: GPD pocket fan: Use a min-speed of 2 while charging Hans de Goede
  2018-01-19 20:47 ` [PATCH 3/3] platform/x86: GPD pocket fan: Stop work on suspend Hans de Goede
  0 siblings, 2 replies; 4+ messages in thread
From: Hans de Goede @ 2018-01-19 20:47 UTC (permalink / raw)
  To: Darren Hart, Andy Shevchenko
  Cc: Hans de Goede, platform-driver-x86, linux-kernel, James

When we fail to get the temperature, assume the worst and set the speed
to max.

While at it introduce a define for MAX_SPEED.

Cc: James <kernel@madingley.org>
Suggested-by: James <kernel@madingley.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/platform/x86/gpd-pocket-fan.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/platform/x86/gpd-pocket-fan.c b/drivers/platform/x86/gpd-pocket-fan.c
index c6f4d89b1437..1fdf2205730d 100644
--- a/drivers/platform/x86/gpd-pocket-fan.c
+++ b/drivers/platform/x86/gpd-pocket-fan.c
@@ -13,6 +13,8 @@
 #include <linux/thermal.h>
 #include <linux/workqueue.h>
 
+#define MAX_SPEED 3
+
 static int temp_limits[3] = { 55000, 60000, 65000 };
 module_param_array(temp_limits, int, NULL, 0444);
 MODULE_PARM_DESC(temp_limits,
@@ -53,9 +55,8 @@ static void gpd_pocket_fan_worker(struct work_struct *work)
 	if (thermal_zone_get_temp(fan->dts0, &t0) ||
 	    thermal_zone_get_temp(fan->dts1, &t1)) {
 		dev_warn(fan->dev, "Error getting temperature\n");
-		queue_delayed_work(system_wq, &fan->work,
-				   msecs_to_jiffies(1000));
-		return;
+		speed = MAX_SPEED;
+		goto set_speed;
 	}
 
 	temp = max(t0, t1);
@@ -79,8 +80,9 @@ static void gpd_pocket_fan_worker(struct work_struct *work)
 		speed = i;
 
 	if (fan->last_speed <= 0 && speed)
-		speed = 3; /* kick start motor */
+		speed = MAX_SPEED; /* kick start motor */
 
+set_speed:
 	gpd_pocket_fan_set_speed(fan, speed);
 
 	/* When mostly idle (low temp/speed), slow down the poll interval. */
-- 
2.14.3

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

* [PATCH 2/3] platform/x86: GPD pocket fan: Use a min-speed of 2 while charging
  2018-01-19 20:47 [PATCH 1/3] platform/x86: GPD pocket fan: Set speed to max on get_temp failure Hans de Goede
@ 2018-01-19 20:47 ` Hans de Goede
  2018-01-19 20:47 ` [PATCH 3/3] platform/x86: GPD pocket fan: Stop work on suspend Hans de Goede
  1 sibling, 0 replies; 4+ messages in thread
From: Hans de Goede @ 2018-01-19 20:47 UTC (permalink / raw)
  To: Darren Hart, Andy Shevchenko
  Cc: Hans de Goede, platform-driver-x86, linux-kernel, James

Newer versions of the GPD pocket BIOS set the fan-speed to 2 when a
charger gets plugged in while the device is off. Mirror this in our
fan driver and use a minimum speed of 2 while charging,

Cc: James <kernel@madingley.org>
Suggested-by: James <kernel@madingley.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/platform/x86/gpd-pocket-fan.c | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/platform/x86/gpd-pocket-fan.c b/drivers/platform/x86/gpd-pocket-fan.c
index 1fdf2205730d..f7b4980c0aa6 100644
--- a/drivers/platform/x86/gpd-pocket-fan.c
+++ b/drivers/platform/x86/gpd-pocket-fan.c
@@ -7,6 +7,7 @@
 
 #include <linux/acpi.h>
 #include <linux/gpio/consumer.h>
+#include <linux/power_supply.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
@@ -25,6 +26,11 @@ module_param(hysteresis, int, 0444);
 MODULE_PARM_DESC(hysteresis,
 		 "Hysteresis in milli-celcius before lowering the fan speed");
 
+static int speed_on_ac = 2;
+module_param(speed_on_ac, int, 0444);
+MODULE_PARM_DESC(speed_on_ac,
+		 "minimum fan speed to allow when system is powered by AC");
+
 struct gpd_pocket_fan_data {
 	struct device *dev;
 	struct thermal_zone_device *dts0;
@@ -46,11 +52,19 @@ static void gpd_pocket_fan_set_speed(struct gpd_pocket_fan_data *fan, int speed)
 	fan->last_speed = speed;
 }
 
+static int gpd_pocket_fan_min_speed(void)
+{
+	if (power_supply_is_system_supplied())
+		return speed_on_ac;
+	else
+		return 0;
+}
+
 static void gpd_pocket_fan_worker(struct work_struct *work)
 {
 	struct gpd_pocket_fan_data *fan =
 		container_of(work, struct gpd_pocket_fan_data, work.work);
-	int t0, t1, temp, speed, i;
+	int t0, t1, temp, speed, min_speed, i;
 
 	if (thermal_zone_get_temp(fan->dts0, &t0) ||
 	    thermal_zone_get_temp(fan->dts1, &t1)) {
@@ -62,9 +76,10 @@ static void gpd_pocket_fan_worker(struct work_struct *work)
 	temp = max(t0, t1);
 
 	speed = fan->last_speed;
+	min_speed = gpd_pocket_fan_min_speed();
 
 	/* Determine minimum speed */
-	for (i = 0; i < ARRAY_SIZE(temp_limits); i++) {
+	for (i = min_speed; i < ARRAY_SIZE(temp_limits); i++) {
 		if (temp < temp_limits[i])
 			break;
 	}
@@ -72,7 +87,7 @@ static void gpd_pocket_fan_worker(struct work_struct *work)
 		speed = i;
 
 	/* Use hysteresis before lowering speed again */
-	for (i = 0; i < ARRAY_SIZE(temp_limits); i++) {
+	for (i = min_speed; i < ARRAY_SIZE(temp_limits); i++) {
 		if (temp <= (temp_limits[i] - hysteresis))
 			break;
 	}
@@ -113,6 +128,11 @@ static int gpd_pocket_fan_probe(struct platform_device *pdev)
 			hysteresis);
 		return -EINVAL;
 	}
+	if (speed_on_ac < 0 || speed_on_ac > MAX_SPEED) {
+		dev_err(&pdev->dev, "Invalid speed_on_ac %d (must be between 0 and 3)\n",
+			speed_on_ac);
+		return -EINVAL;
+	}
 
 	fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL);
 	if (!fan)
@@ -157,7 +177,7 @@ static int gpd_pocket_fan_suspend(struct device *dev)
 {
 	struct gpd_pocket_fan_data *fan = dev_get_drvdata(dev);
 
-	gpd_pocket_fan_set_speed(fan, 0);
+	gpd_pocket_fan_set_speed(fan, gpd_pocket_fan_min_speed());
 	return 0;
 }
 
-- 
2.14.3

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

* [PATCH 3/3] platform/x86: GPD pocket fan: Stop work on suspend
  2018-01-19 20:47 [PATCH 1/3] platform/x86: GPD pocket fan: Set speed to max on get_temp failure Hans de Goede
  2018-01-19 20:47 ` [PATCH 2/3] platform/x86: GPD pocket fan: Use a min-speed of 2 while charging Hans de Goede
@ 2018-01-19 20:47 ` Hans de Goede
  2018-01-26 15:29   ` Andy Shevchenko
  1 sibling, 1 reply; 4+ messages in thread
From: Hans de Goede @ 2018-01-19 20:47 UTC (permalink / raw)
  To: Darren Hart, Andy Shevchenko
  Cc: Hans de Goede, platform-driver-x86, linux-kernel

Stop the work on suspend, otherwise it may run between our suspend method
running and the system suspending, possibly restarting the fan which
we've just stopped.

Note we already requeue the work on resume, so that we get a fresh speed
at resume.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/platform/x86/gpd-pocket-fan.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/platform/x86/gpd-pocket-fan.c b/drivers/platform/x86/gpd-pocket-fan.c
index f7b4980c0aa6..6425c9b49caa 100644
--- a/drivers/platform/x86/gpd-pocket-fan.c
+++ b/drivers/platform/x86/gpd-pocket-fan.c
@@ -177,6 +177,7 @@ static int gpd_pocket_fan_suspend(struct device *dev)
 {
 	struct gpd_pocket_fan_data *fan = dev_get_drvdata(dev);
 
+	cancel_delayed_work_sync(&fan->work);
 	gpd_pocket_fan_set_speed(fan, gpd_pocket_fan_min_speed());
 	return 0;
 }
-- 
2.14.3

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

* Re: [PATCH 3/3] platform/x86: GPD pocket fan: Stop work on suspend
  2018-01-19 20:47 ` [PATCH 3/3] platform/x86: GPD pocket fan: Stop work on suspend Hans de Goede
@ 2018-01-26 15:29   ` Andy Shevchenko
  0 siblings, 0 replies; 4+ messages in thread
From: Andy Shevchenko @ 2018-01-26 15:29 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Darren Hart, Andy Shevchenko, Platform Driver, Linux Kernel Mailing List

On Fri, Jan 19, 2018 at 10:47 PM, Hans de Goede <hdegoede@redhat.com> wrote:
> Stop the work on suspend, otherwise it may run between our suspend method
> running and the system suspending, possibly restarting the fan which
> we've just stopped.
>
> Note we already requeue the work on resume, so that we get a fresh speed
> at resume.

All three pushed to my reviewing and testing queue, thanks!

>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/platform/x86/gpd-pocket-fan.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/platform/x86/gpd-pocket-fan.c b/drivers/platform/x86/gpd-pocket-fan.c
> index f7b4980c0aa6..6425c9b49caa 100644
> --- a/drivers/platform/x86/gpd-pocket-fan.c
> +++ b/drivers/platform/x86/gpd-pocket-fan.c
> @@ -177,6 +177,7 @@ static int gpd_pocket_fan_suspend(struct device *dev)
>  {
>         struct gpd_pocket_fan_data *fan = dev_get_drvdata(dev);
>
> +       cancel_delayed_work_sync(&fan->work);
>         gpd_pocket_fan_set_speed(fan, gpd_pocket_fan_min_speed());
>         return 0;
>  }
> --
> 2.14.3
>



-- 
With Best Regards,
Andy Shevchenko

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

end of thread, other threads:[~2018-01-26 15:29 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-19 20:47 [PATCH 1/3] platform/x86: GPD pocket fan: Set speed to max on get_temp failure Hans de Goede
2018-01-19 20:47 ` [PATCH 2/3] platform/x86: GPD pocket fan: Use a min-speed of 2 while charging Hans de Goede
2018-01-19 20:47 ` [PATCH 3/3] platform/x86: GPD pocket fan: Stop work on suspend Hans de Goede
2018-01-26 15:29   ` Andy Shevchenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).