All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/18] au0828: Fix suspend/resume
@ 2014-08-10  0:47 Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 01/18] [media] au0828: avoid race conditions at RC stop Mauro Carvalho Chehab
                   ` (17 more replies)
  0 siblings, 18 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

Suspend/resume can be very tricky. That's the second attempt to fix
it with au0828.

With this patchset, suspend/resume to ram works fine if the device
is not being used. After resume, IR, digital TV and analog TV
keeps working.

On my tests, however, trying to suspend while watching TV caused
my test machine to crash. I suspect, however, that the bug could
be at the USB driver level.

Anyway, before this series, the device even didn't suspend, so
it is clearly a progress.

Tested on an Odroid-U3 running Tizen with a very light stack. I'll 
test this also on some x86_64 hardware.

Mauro Carvalho Chehab (16):
  [media] au0828: avoid race conditions at RC stop
  [media] au0828: handle IR int during suspend/resume
  [media] au0828: don't let the IR polling thread to run at suspend
  [media] au0828: be sure to reenable the bridge and GPIOs on resume
  [media] au0828: Add suspend code for DVB
  [media] au0828: properly handle stream on/off state
  [media] au0828: add suspend/resume code for V4L2
  [media] au0828: Remove a bad whitespace
  [media] au0828: use pr_foo macros
  [media] au0828: add pr_info to track au0828 suspend/resume code
  [media] dvb-frontend: add core support for tuner suspend/resume
  [media] xc5000: fix xc5000 suspend
  [media] au0828: move the code that sets DTV on a separate function
  [media] xc5000: Split config and set code for analog/radio
  [media] xc5000: add a resume function
  [media] xc5000: better name the functions

Shuah Khan (2):
  [media] au0828: add au0828_rc_*() stubs for VIDEO_AU0828_RC disabled
    case
  [media] au0828: remove CONFIG_VIDEO_AU0828_RC scope around
    au0828_rc_*()

 drivers/media/dvb-core/dvb_frontend.c   |   8 +-
 drivers/media/dvb-core/dvb_frontend.h   |   2 +
 drivers/media/tuners/xc5000.c           | 184 +++++++++++++++++++++-----------
 drivers/media/usb/au0828/au0828-cards.c |  13 ++-
 drivers/media/usb/au0828/au0828-core.c  |  84 +++++++++++----
 drivers/media/usb/au0828/au0828-dvb.c   |  85 ++++++++++-----
 drivers/media/usb/au0828/au0828-i2c.c   |  15 +--
 drivers/media/usb/au0828/au0828-input.c |  20 +++-
 drivers/media/usb/au0828/au0828-vbi.c   |   4 +-
 drivers/media/usb/au0828/au0828-video.c |  90 +++++++++++++---
 drivers/media/usb/au0828/au0828.h       |  29 +++--
 drivers/media/v4l2-core/tuner-core.c    |   8 +-
 12 files changed, 387 insertions(+), 155 deletions(-)

-- 
1.9.3


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

* [PATCH v2 01/18] [media] au0828: avoid race conditions at RC stop
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 02/18] [media] au0828: handle IR int during suspend/resume Mauro Carvalho Chehab
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

As the RC kthread can re-enable IR int, we should first
cancel the kthread and then disable IR int.

While here, remove a temporary debug printk.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/usb/au0828/au0828-input.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c
index f0c5672e5f56..47ef07a693af 100644
--- a/drivers/media/usb/au0828/au0828-input.c
+++ b/drivers/media/usb/au0828/au0828-input.c
@@ -253,10 +253,10 @@ static void au0828_rc_stop(struct rc_dev *rc)
 {
 	struct au0828_rc *ir = rc->priv;
 
+	cancel_delayed_work_sync(&ir->work);
+
 	/* Disable IR */
 	au8522_rc_clear(ir, 0xe0, 1 << 4);
-
-	cancel_delayed_work_sync(&ir->work);
 }
 
 static int au0828_probe_i2c_ir(struct au0828_dev *dev)
-- 
1.9.3


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

* [PATCH v2 02/18] [media] au0828: handle IR int during suspend/resume
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 01/18] [media] au0828: avoid race conditions at RC stop Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 03/18] [media] au0828: add au0828_rc_*() stubs for VIDEO_AU0828_RC disabled case Mauro Carvalho Chehab
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

It doesn't make sense to handle an IR code given before
suspending after the device resume. So, turn off IR
int while suspending.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/usb/au0828/au0828-input.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c
index 47ef07a693af..7a5437a4d938 100644
--- a/drivers/media/usb/au0828/au0828-input.c
+++ b/drivers/media/usb/au0828/au0828-input.c
@@ -380,6 +380,9 @@ int au0828_rc_suspend(struct au0828_dev *dev)
 
 	cancel_delayed_work_sync(&ir->work);
 
+	/* Disable IR */
+	au8522_rc_clear(ir, 0xe0, 1 << 4);
+
 	return 0;
 }
 
@@ -390,6 +393,9 @@ int au0828_rc_resume(struct au0828_dev *dev)
 	if (!ir)
 		return 0;
 
+	/* Enable IR */
+	au8522_rc_set(ir, 0xe0, 1 << 4);
+
 	schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
 
 	return 0;
-- 
1.9.3


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

* [PATCH v2 03/18] [media] au0828: add au0828_rc_*() stubs for VIDEO_AU0828_RC disabled case
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 01/18] [media] au0828: avoid race conditions at RC stop Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 02/18] [media] au0828: handle IR int during suspend/resume Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 04/18] [media] au0828: remove CONFIG_VIDEO_AU0828_RC scope around au0828_rc_*() Mauro Carvalho Chehab
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Linux Media Mailing List, Mauro Carvalho Chehab,
	Mauro Carvalho Chehab

From: Shuah Khan <shuah.kh@samsung.com>

Define au0828_rc_*() stubs to avoid compile errors when
VIDEO_AU0828_RC is disabled and avoid the need to enclose
au0828_rc_*() in ifdef CONFIG_VIDEO_AU0828_RC in .c files.

Signed-off-by: Shuah Khan <shuah.kh@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/usb/au0828/au0828.h | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index 96bec05d7dac..fd0916e20323 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -326,7 +326,14 @@ extern struct videobuf_queue_ops au0828_vbi_qops;
 	} while (0)
 
 /* au0828-input.c */
-int au0828_rc_register(struct au0828_dev *dev);
-void au0828_rc_unregister(struct au0828_dev *dev);
-int au0828_rc_suspend(struct au0828_dev *dev);
-int au0828_rc_resume(struct au0828_dev *dev);
+#ifdef CONFIG_VIDEO_AU0828_RC
+extern int au0828_rc_register(struct au0828_dev *dev);
+extern void au0828_rc_unregister(struct au0828_dev *dev);
+extern int au0828_rc_suspend(struct au0828_dev *dev);
+extern int au0828_rc_resume(struct au0828_dev *dev);
+#else
+static inline int au0828_rc_register(struct au0828_dev *dev) { return 0; }
+static inline void au0828_rc_unregister(struct au0828_dev *dev) { }
+static inline int au0828_rc_suspend(struct au0828_dev *dev) { return 0; }
+static inline int au0828_rc_resume(struct au0828_dev *dev) { return 0; }
+#endif
-- 
1.9.3


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

* [PATCH v2 04/18] [media] au0828: remove CONFIG_VIDEO_AU0828_RC scope around au0828_rc_*()
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
                   ` (2 preceding siblings ...)
  2014-08-10  0:47 ` [PATCH v2 03/18] [media] au0828: add au0828_rc_*() stubs for VIDEO_AU0828_RC disabled case Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 05/18] [media] au0828: don't let the IR polling thread to run at suspend Mauro Carvalho Chehab
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Linux Media Mailing List, Mauro Carvalho Chehab,
	Mauro Carvalho Chehab

From: Shuah Khan <shuah.kh@samsung.com>

Remove CONFIG_VIDEO_AU0828_RC scope around au0828_rc_register()
and au0828_rc_unregister() calls in au0828-core

Signed-off-by: Shuah Khan <shuah.kh@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 56025e689442..b08b979bb9a7 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -153,9 +153,7 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
 
 	dprintk(1, "%s()\n", __func__);
 
-#ifdef CONFIG_VIDEO_AU0828_RC
 	au0828_rc_unregister(dev);
-#endif
 	/* Digital TV */
 	au0828_dvb_unregister(dev);
 
@@ -266,10 +264,8 @@ static int au0828_usb_probe(struct usb_interface *interface,
 		pr_err("%s() au0282_dev_register failed\n",
 		       __func__);
 
-#ifdef CONFIG_VIDEO_AU0828_RC
 	/* Remote controller */
 	au0828_rc_register(dev);
-#endif
 
 	/*
 	 * Store the pointer to the au0828_dev so it can be accessed in
-- 
1.9.3


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

* [PATCH v2 05/18] [media] au0828: don't let the IR polling thread to run at suspend
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
                   ` (3 preceding siblings ...)
  2014-08-10  0:47 ` [PATCH v2 04/18] [media] au0828: remove CONFIG_VIDEO_AU0828_RC scope around au0828_rc_*() Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 06/18] [media] au0828: be sure to reenable the bridge and GPIOs on resume Mauro Carvalho Chehab
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

Trying to make au0828 to suspend can do very bad things, as
the polling Kthread is not handled. We should disable it
during suspend, only re-enabling it at resume.

Still, analog and digital TV won't work, as we don't reinit
the settings at resume, but at least it won't hang.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index b08b979bb9a7..3a02de142f9f 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -281,13 +281,42 @@ static int au0828_usb_probe(struct usb_interface *interface,
 	return retval;
 }
 
+static int au0828_suspend(struct usb_interface *interface,
+				pm_message_t message)
+{
+	struct au0828_dev *dev = usb_get_intfdata(interface);
+
+	if (!dev)
+		return 0;
+
+	au0828_rc_suspend(dev);
+
+	/* FIXME: should suspend also ATV/DTV */
+
+	return 0;
+}
+
+static int au0828_resume(struct usb_interface *interface)
+{
+	struct au0828_dev *dev = usb_get_intfdata(interface);
+	if (!dev)
+		return 0;
+
+	au0828_rc_resume(dev);
+
+	/* FIXME: should resume also ATV/DTV */
+
+	return 0;
+}
+
 static struct usb_driver au0828_usb_driver = {
 	.name		= DRIVER_NAME,
 	.probe		= au0828_usb_probe,
 	.disconnect	= au0828_usb_disconnect,
 	.id_table	= au0828_usb_id_table,
-
-	/* FIXME: Add suspend and resume functions */
+	.suspend	= au0828_suspend,
+	.resume		= au0828_resume,
+	.reset_resume	= au0828_resume,
 };
 
 static int __init au0828_init(void)
-- 
1.9.3


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

* [PATCH v2 06/18] [media] au0828: be sure to reenable the bridge and GPIOs on resume
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
                   ` (4 preceding siblings ...)
  2014-08-10  0:47 ` [PATCH v2 05/18] [media] au0828: don't let the IR polling thread to run at suspend Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 07/18] [media] au0828: Add suspend code for DVB Mauro Carvalho Chehab
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

At resume, we should restore the register contents. So,
reenable the bridge and GPIO settings.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 3a02de142f9f..87340a8af7d7 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -302,6 +302,12 @@ static int au0828_resume(struct usb_interface *interface)
 	if (!dev)
 		return 0;
 
+	/* Power Up the bridge */
+	au0828_write(dev, REG_600, 1 << 4);
+
+	/* Bring up the GPIO's and supporting devices */
+	au0828_gpio_setup(dev);
+
 	au0828_rc_resume(dev);
 
 	/* FIXME: should resume also ATV/DTV */
-- 
1.9.3


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

* [PATCH v2 07/18] [media] au0828: Add suspend code for DVB
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
                   ` (5 preceding siblings ...)
  2014-08-10  0:47 ` [PATCH v2 06/18] [media] au0828: be sure to reenable the bridge and GPIOs on resume Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 08/18] [media] au0828: properly handle stream on/off state Mauro Carvalho Chehab
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

The scheduled work should be cancelled during suspend.

At resume time, we need to set the frontend again. So,
add such logic to the driver.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c |  2 ++
 drivers/media/usb/au0828/au0828-dvb.c  | 31 ++++++++++++++++++++++++++++++-
 drivers/media/usb/au0828/au0828.h      |  2 ++
 3 files changed, 34 insertions(+), 1 deletion(-)
 mode change 100644 => 100755 drivers/media/usb/au0828/au0828-dvb.c

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 87340a8af7d7..26ec50539dc4 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -290,6 +290,7 @@ static int au0828_suspend(struct usb_interface *interface,
 		return 0;
 
 	au0828_rc_suspend(dev);
+	au0828_dvb_suspend(dev);
 
 	/* FIXME: should suspend also ATV/DTV */
 
@@ -309,6 +310,7 @@ static int au0828_resume(struct usb_interface *interface)
 	au0828_gpio_setup(dev);
 
 	au0828_rc_resume(dev);
+	au0828_dvb_resume(dev);
 
 	/* FIXME: should resume also ATV/DTV */
 
diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c
old mode 100644
new mode 100755
index d8b5d9480279..7b6e71065aa4
--- a/drivers/media/usb/au0828/au0828-dvb.c
+++ b/drivers/media/usb/au0828/au0828-dvb.c
@@ -23,7 +23,6 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/device.h>
-#include <linux/suspend.h>
 #include <media/v4l2-common.h>
 #include <media/tuner.h>
 
@@ -618,3 +617,33 @@ int au0828_dvb_register(struct au0828_dev *dev)
 
 	return 0;
 }
+
+void au0828_dvb_suspend(struct au0828_dev *dev)
+{
+	struct au0828_dvb *dvb = &dev->dvb;
+
+	if (dvb && dev->urb_streaming) {
+		cancel_work_sync(&dev->restart_streaming);
+
+		/* Stop transport */
+		mutex_lock(&dvb->lock);
+		stop_urb_transfer(dev);
+		au0828_stop_transport(dev, 1);
+		mutex_unlock(&dvb->lock);
+	}
+}
+
+void au0828_dvb_resume(struct au0828_dev *dev)
+{
+	struct au0828_dvb *dvb = &dev->dvb;
+
+	if (dvb && dev->urb_streaming) {
+		au0828_set_frontend(dvb->frontend);
+
+		/* Start transport */
+		mutex_lock(&dvb->lock);
+		au0828_start_transport(dev);
+		start_urb_transfer(dev);
+		mutex_unlock(&dvb->lock);
+	}
+}
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index fd0916e20323..d32234353096 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -316,6 +316,8 @@ void au0828_analog_unregister(struct au0828_dev *dev);
 /* au0828-dvb.c */
 extern int au0828_dvb_register(struct au0828_dev *dev);
 extern void au0828_dvb_unregister(struct au0828_dev *dev);
+void au0828_dvb_suspend(struct au0828_dev *dev);
+void au0828_dvb_resume(struct au0828_dev *dev);
 
 /* au0828-vbi.c */
 extern struct videobuf_queue_ops au0828_vbi_qops;
-- 
1.9.3


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

* [PATCH v2 08/18] [media] au0828: properly handle stream on/off state
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
                   ` (6 preceding siblings ...)
  2014-08-10  0:47 ` [PATCH v2 07/18] [media] au0828: Add suspend code for DVB Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 09/18] [media] au0828: add suspend/resume code for V4L2 Mauro Carvalho Chehab
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

The STREAM_ON state is used by s_format callback,
but the driver never sets it.

Fix it. This will also be needed in order to handle
suspend/resume ops.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/usb/au0828/au0828-video.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 98f7ea1d6d63..36ff3b496f87 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -159,6 +159,7 @@ static void au0828_irq_callback(struct urb *urb)
 		au0828_isocdbg("urb resubmit failed (error=%i)\n",
 			       urb->status);
 	}
+	dev->stream_state = STREAM_ON;
 }
 
 /*
@@ -198,6 +199,8 @@ static void au0828_uninit_isoc(struct au0828_dev *dev)
 	dev->isoc_ctl.urb = NULL;
 	dev->isoc_ctl.transfer_buffer = NULL;
 	dev->isoc_ctl.num_bufs = 0;
+
+	dev->stream_state = STREAM_OFF;
 }
 
 /*
-- 
1.9.3


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

* [PATCH v2 09/18] [media] au0828: add suspend/resume code for V4L2
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
                   ` (7 preceding siblings ...)
  2014-08-10  0:47 ` [PATCH v2 08/18] [media] au0828: properly handle stream on/off state Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 10/18] [media] au0828: Remove a bad whitespace Mauro Carvalho Chehab
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

No timers should be enabled during suspend. So,
stop them. At resume time, we should do the proper
initialization for it to keep working.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c  |  2 ++
 drivers/media/usb/au0828/au0828-video.c | 59 ++++++++++++++++++++++++++++++++-
 drivers/media/usb/au0828/au0828.h       |  7 ++++
 3 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 26ec50539dc4..5f13888d73a0 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -290,6 +290,7 @@ static int au0828_suspend(struct usb_interface *interface,
 		return 0;
 
 	au0828_rc_suspend(dev);
+	au0828_v4l2_suspend(dev);
 	au0828_dvb_suspend(dev);
 
 	/* FIXME: should suspend also ATV/DTV */
@@ -310,6 +311,7 @@ static int au0828_resume(struct usb_interface *interface)
 	au0828_gpio_setup(dev);
 
 	au0828_rc_resume(dev);
+	au0828_v4l2_resume(dev);
 	au0828_dvb_resume(dev);
 
 	/* FIXME: should resume also ATV/DTV */
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 36ff3b496f87..574a08c7013d 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -32,7 +32,6 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/device.h>
-#include <linux/suspend.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-event.h>
@@ -1871,6 +1870,64 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
 	return rc;
 }
 
+void au0828_v4l2_suspend(struct au0828_dev *dev)
+{
+	struct urb *urb;
+	int i;
+
+	if (dev->stream_state == STREAM_ON) {
+		au0828_analog_stream_disable(dev);
+		/* stop urbs */
+		for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
+			urb = dev->isoc_ctl.urb[i];
+			if (urb) {
+				if (!irqs_disabled())
+					usb_kill_urb(urb);
+				else
+					usb_unlink_urb(urb);
+			}
+		}
+	}
+
+	if (dev->vid_timeout_running)
+		del_timer_sync(&dev->vid_timeout);
+	if (dev->vbi_timeout_running)
+		del_timer_sync(&dev->vbi_timeout);
+}
+
+void au0828_v4l2_resume(struct au0828_dev *dev)
+{
+	int i, rc;
+
+	if (dev->stream_state == STREAM_ON) {
+		au0828_stream_interrupt(dev);
+		au0828_init_tuner(dev);
+	}
+
+	if (dev->vid_timeout_running)
+		mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
+	if (dev->vbi_timeout_running)
+		mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
+
+	/* If we were doing ac97 instead of i2s, it would go here...*/
+	au0828_i2s_init(dev);
+
+	au0828_analog_stream_enable(dev);
+
+	if (!(dev->stream_state == STREAM_ON)) {
+		au0828_analog_stream_reset(dev);
+		/* submit urbs */
+		for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
+			rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC);
+			if (rc) {
+				au0828_isocdbg("submit of urb %i failed (error=%i)\n",
+					       i, rc);
+				au0828_uninit_isoc(dev);
+			}
+		}
+	}
+}
+
 static struct v4l2_file_operations au0828_v4l_fops = {
 	.owner      = THIS_MODULE,
 	.open       = au0828_v4l2_open,
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index d32234353096..0d8cfe5cd264 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -311,6 +311,13 @@ int au0828_analog_register(struct au0828_dev *dev,
 			   struct usb_interface *interface);
 int au0828_analog_stream_disable(struct au0828_dev *d);
 void au0828_analog_unregister(struct au0828_dev *dev);
+#ifdef CONFIG_VIDEO_AU0828_V4L2
+void au0828_v4l2_suspend(struct au0828_dev *dev);
+void au0828_v4l2_resume(struct au0828_dev *dev);
+#else
+static inline void au0828_v4l2_suspend(struct au0828_dev *dev) { };
+static inline void au0828_v4l2_resume(struct au0828_dev *dev) { };
+#endif
 
 /* ----------------------------------------------------------- */
 /* au0828-dvb.c */
-- 
1.9.3


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

* [PATCH v2 10/18] [media] au0828: Remove a bad whitespace
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
                   ` (8 preceding siblings ...)
  2014-08-10  0:47 ` [PATCH v2 09/18] [media] au0828: add suspend/resume code for V4L2 Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 11/18] [media] au0828: use pr_foo macros Mauro Carvalho Chehab
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/usb/au0828/au0828-dvb.c   | 0
 drivers/media/usb/au0828/au0828-input.c | 2 +-
 2 files changed, 1 insertion(+), 1 deletion(-)
 mode change 100755 => 100644 drivers/media/usb/au0828/au0828-dvb.c

diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c
old mode 100755
new mode 100644
diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c
index 7a5437a4d938..5efb83977f39 100644
--- a/drivers/media/usb/au0828/au0828-input.c
+++ b/drivers/media/usb/au0828/au0828-input.c
@@ -133,7 +133,7 @@ static int au0828_get_key_au8522(struct au0828_rc *ir)
 	rc = au8522_rc_read(ir, 0xe1, -1, buf, 1);
 	if (rc < 0 || !(buf[0] & (1 << 4))) {
 		/* Be sure that IR is enabled */
-	        au8522_rc_set(ir, 0xe0, 1 << 4);
+		au8522_rc_set(ir, 0xe0, 1 << 4);
 		return 0;
 	}
 
-- 
1.9.3


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

* [PATCH v2 11/18] [media] au0828: use pr_foo macros
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
                   ` (9 preceding siblings ...)
  2014-08-10  0:47 ` [PATCH v2 10/18] [media] au0828: Remove a bad whitespace Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 12/18] [media] au0828: add pr_info to track au0828 suspend/resume code Mauro Carvalho Chehab
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

Instead of using printk(KERN_foo, use pr_foo() macros.

No functional changes.

Note: we should do the same for dprintk(), but that would
require to remove the dprintk levels. So, for now, let's
not touch on it.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/usb/au0828/au0828-cards.c | 13 ++++-----
 drivers/media/usb/au0828/au0828-core.c  | 33 +++++++++++-----------
 drivers/media/usb/au0828/au0828-dvb.c   | 50 +++++++++++++++------------------
 drivers/media/usb/au0828/au0828-i2c.c   | 15 +++++-----
 drivers/media/usb/au0828/au0828-input.c |  4 +--
 drivers/media/usb/au0828/au0828-vbi.c   |  4 +--
 drivers/media/usb/au0828/au0828-video.c | 23 +++++++--------
 drivers/media/usb/au0828/au0828.h       |  5 ++--
 8 files changed, 72 insertions(+), 75 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-cards.c b/drivers/media/usb/au0828/au0828-cards.c
index b6c9d1f466bd..d229c6dbddb9 100644
--- a/drivers/media/usb/au0828/au0828-cards.c
+++ b/drivers/media/usb/au0828/au0828-cards.c
@@ -143,8 +143,7 @@ int au0828_tuner_callback(void *priv, int component, int command, int arg)
 			mdelay(10);
 			return 0;
 		} else {
-			printk(KERN_ERR
-				"%s(): Unknown command.\n", __func__);
+			pr_err("%s(): Unknown command.\n", __func__);
 			return -EINVAL;
 		}
 		break;
@@ -178,12 +177,12 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data)
 	case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */
 		break;
 	default:
-		printk(KERN_WARNING "%s: warning: "
-		       "unknown hauppauge model #%d\n", __func__, tv.model);
+		pr_warn("%s: warning: unknown hauppauge model #%d\n",
+			__func__, tv.model);
 		break;
 	}
 
-	printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n",
+	pr_info("%s: hauppauge eeprom: model=%d\n",
 	       __func__, tv.model);
 }
 
@@ -229,7 +228,7 @@ void au0828_card_analog_fe_setup(struct au0828_dev *dev)
 		sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
 				"au8522", 0x8e >> 1, NULL);
 		if (sd == NULL)
-			printk(KERN_ERR "analog subdev registration failed\n");
+			pr_err("analog subdev registration failed\n");
 	}
 
 	/* Setup tuners */
@@ -238,7 +237,7 @@ void au0828_card_analog_fe_setup(struct au0828_dev *dev)
 		sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
 				"tuner", dev->board.tuner_addr, NULL);
 		if (sd == NULL)
-			printk(KERN_ERR "tuner subdev registration fail\n");
+			pr_err("tuner subdev registration fail\n");
 
 		tun_setup.mode_mask      = mode_mask;
 		tun_setup.type           = dev->board.tuner_type;
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 5f13888d73a0..452d14249348 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -19,14 +19,14 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include "au0828.h"
+
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <linux/mutex.h>
 
-#include "au0828.h"
-
 /*
  * 1 = General debug messages
  * 2 = USB handling
@@ -90,7 +90,7 @@ static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value,
 		status = min(status, 0);
 
 		if (status < 0) {
-			printk(KERN_ERR "%s() Failed sending control message, error %d.\n",
+			pr_err("%s() Failed sending control message, error %d.\n",
 				__func__, status);
 		}
 
@@ -115,7 +115,7 @@ static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value,
 		status = min(status, 0);
 
 		if (status < 0) {
-			printk(KERN_ERR "%s() Failed receiving control message, error %d.\n",
+			pr_err("%s() Failed receiving control message, error %d.\n",
 				__func__, status);
 		}
 
@@ -197,15 +197,14 @@ static int au0828_usb_probe(struct usb_interface *interface,
 	 * not enough even for most Digital TV streams.
 	 */
 	if (usbdev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) {
-		printk(KERN_ERR "au0828: Device initialization failed.\n");
-		printk(KERN_ERR "au0828: Device must be connected to a "
-		       "high-speed USB 2.0 port.\n");
+		pr_err("au0828: Device initialization failed.\n");
+		pr_err("au0828: Device must be connected to a high-speed USB 2.0 port.\n");
 		return -ENODEV;
 	}
 
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (dev == NULL) {
-		printk(KERN_ERR "%s() Unable to allocate memory\n", __func__);
+		pr_err("%s() Unable to allocate memory\n", __func__);
 		return -ENOMEM;
 	}
 
@@ -273,7 +272,7 @@ static int au0828_usb_probe(struct usb_interface *interface,
 	 */
 	usb_set_intfdata(interface, dev);
 
-	printk(KERN_INFO "Registered device AU0828 [%s]\n",
+	pr_info("Registered device AU0828 [%s]\n",
 		dev->board.name == NULL ? "Unset" : dev->board.name);
 
 	mutex_unlock(&dev->lock);
@@ -320,7 +319,7 @@ static int au0828_resume(struct usb_interface *interface)
 }
 
 static struct usb_driver au0828_usb_driver = {
-	.name		= DRIVER_NAME,
+	.name		= KBUILD_MODNAME,
 	.probe		= au0828_usb_probe,
 	.disconnect	= au0828_usb_disconnect,
 	.id_table	= au0828_usb_id_table,
@@ -334,27 +333,27 @@ static int __init au0828_init(void)
 	int ret;
 
 	if (au0828_debug & 1)
-		printk(KERN_INFO "%s() Debugging is enabled\n", __func__);
+		pr_info("%s() Debugging is enabled\n", __func__);
 
 	if (au0828_debug & 2)
-		printk(KERN_INFO "%s() USB Debugging is enabled\n", __func__);
+		pr_info("%s() USB Debugging is enabled\n", __func__);
 
 	if (au0828_debug & 4)
-		printk(KERN_INFO "%s() I2C Debugging is enabled\n", __func__);
+		pr_info("%s() I2C Debugging is enabled\n", __func__);
 
 	if (au0828_debug & 8)
-		printk(KERN_INFO "%s() Bridge Debugging is enabled\n",
+		pr_info("%s() Bridge Debugging is enabled\n",
 		       __func__);
 
 	if (au0828_debug & 16)
-		printk(KERN_INFO "%s() IR Debugging is enabled\n",
+		pr_info("%s() IR Debugging is enabled\n",
 		       __func__);
 
-	printk(KERN_INFO "au0828 driver loaded\n");
+	pr_info("au0828 driver loaded\n");
 
 	ret = usb_register(&au0828_usb_driver);
 	if (ret)
-		printk(KERN_ERR "usb_register failed, error = %d\n", ret);
+		pr_err("usb_register failed, error = %d\n", ret);
 
 	return ret;
 }
diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c
index 7b6e71065aa4..99cf83bca033 100644
--- a/drivers/media/usb/au0828/au0828-dvb.c
+++ b/drivers/media/usb/au0828/au0828-dvb.c
@@ -19,6 +19,8 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include "au0828.h"
+
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/init.h>
@@ -26,7 +28,6 @@
 #include <media/v4l2-common.h>
 #include <media/tuner.h>
 
-#include "au0828.h"
 #include "au8522.h"
 #include "xc5000.h"
 #include "mxl5007t.h"
@@ -126,7 +127,7 @@ static void urb_completion(struct urb *purb)
 	}
 
 	if (ptype != PIPE_BULK) {
-		printk(KERN_ERR "%s: Unsupported URB type %d\n",
+		pr_err("%s: Unsupported URB type %d\n",
 		       __func__, ptype);
 		return;
 	}
@@ -201,8 +202,7 @@ static int start_urb_transfer(struct au0828_dev *dev)
 		if (!purb->transfer_buffer) {
 			usb_free_urb(purb);
 			dev->urbs[i] = NULL;
-			printk(KERN_ERR
-			       "%s: failed big buffer allocation, err = %d\n",
+			pr_err("%s: failed big buffer allocation, err = %d\n",
 			       __func__, ret);
 			goto err;
 		}
@@ -223,8 +223,8 @@ static int start_urb_transfer(struct au0828_dev *dev)
 		ret = usb_submit_urb(dev->urbs[i], GFP_ATOMIC);
 		if (ret != 0) {
 			stop_urb_transfer(dev);
-			printk(KERN_ERR "%s: failed urb submission, "
-			       "err = %d\n", __func__, ret);
+			pr_err("%s: failed urb submission, err = %d\n",
+			       __func__, ret);
 			return ret;
 		}
 	}
@@ -392,9 +392,8 @@ static int dvb_register(struct au0828_dev *dev)
 			if (!dev->dig_transfer_buffer[i]) {
 				result = -ENOMEM;
 
-				printk(KERN_ERR
-				       "%s: failed buffer allocation (errno = %d)\n",
-				       DRIVER_NAME, result);
+				pr_err("failed buffer allocation (errno = %d)\n",
+				       result);
 				goto fail_adapter;
 			}
 		}
@@ -403,11 +402,12 @@ static int dvb_register(struct au0828_dev *dev)
 	INIT_WORK(&dev->restart_streaming, au0828_restart_dvb_streaming);
 
 	/* register adapter */
-	result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE,
+	result = dvb_register_adapter(&dvb->adapter,
+				      KBUILD_MODNAME, THIS_MODULE,
 				      &dev->usbdev->dev, adapter_nr);
 	if (result < 0) {
-		printk(KERN_ERR "%s: dvb_register_adapter failed "
-		       "(errno = %d)\n", DRIVER_NAME, result);
+		pr_err("dvb_register_adapter failed (errno = %d)\n",
+		       result);
 		goto fail_adapter;
 	}
 	dvb->adapter.priv = dev;
@@ -415,8 +415,8 @@ static int dvb_register(struct au0828_dev *dev)
 	/* register frontend */
 	result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
 	if (result < 0) {
-		printk(KERN_ERR "%s: dvb_register_frontend failed "
-		       "(errno = %d)\n", DRIVER_NAME, result);
+		pr_err("dvb_register_frontend failed (errno = %d)\n",
+		       result);
 		goto fail_frontend;
 	}
 
@@ -435,8 +435,7 @@ static int dvb_register(struct au0828_dev *dev)
 	dvb->demux.stop_feed  = au0828_dvb_stop_feed;
 	result = dvb_dmx_init(&dvb->demux);
 	if (result < 0) {
-		printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n",
-		       DRIVER_NAME, result);
+		pr_err("dvb_dmx_init failed (errno = %d)\n", result);
 		goto fail_dmx;
 	}
 
@@ -445,31 +444,29 @@ static int dvb_register(struct au0828_dev *dev)
 	dvb->dmxdev.capabilities = 0;
 	result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
 	if (result < 0) {
-		printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n",
-		       DRIVER_NAME, result);
+		pr_err("dvb_dmxdev_init failed (errno = %d)\n", result);
 		goto fail_dmxdev;
 	}
 
 	dvb->fe_hw.source = DMX_FRONTEND_0;
 	result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 	if (result < 0) {
-		printk(KERN_ERR "%s: add_frontend failed "
-		       "(DMX_FRONTEND_0, errno = %d)\n", DRIVER_NAME, result);
+		pr_err("add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
+		       result);
 		goto fail_fe_hw;
 	}
 
 	dvb->fe_mem.source = DMX_MEMORY_FE;
 	result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
 	if (result < 0) {
-		printk(KERN_ERR "%s: add_frontend failed "
-		       "(DMX_MEMORY_FE, errno = %d)\n", DRIVER_NAME, result);
+		pr_err("add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
+		       result);
 		goto fail_fe_mem;
 	}
 
 	result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 	if (result < 0) {
-		printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n",
-		       DRIVER_NAME, result);
+		pr_err("connect_frontend failed (errno = %d)\n", result);
 		goto fail_fe_conn;
 	}
 
@@ -595,12 +592,11 @@ int au0828_dvb_register(struct au0828_dev *dev)
 		}
 		break;
 	default:
-		printk(KERN_WARNING "The frontend of your DVB/ATSC card "
-		       "isn't supported yet\n");
+		pr_warn("The frontend of your DVB/ATSC card isn't supported yet\n");
 		break;
 	}
 	if (NULL == dvb->frontend) {
-		printk(KERN_ERR "%s() Frontend initialization failed\n",
+		pr_err("%s() Frontend initialization failed\n",
 		       __func__);
 		return -1;
 	}
diff --git a/drivers/media/usb/au0828/au0828-i2c.c b/drivers/media/usb/au0828/au0828-i2c.c
index daaeaf1b089c..ae7ac6669769 100644
--- a/drivers/media/usb/au0828/au0828-i2c.c
+++ b/drivers/media/usb/au0828/au0828-i2c.c
@@ -19,13 +19,14 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include "au0828.h"
+
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 
-#include "au0828.h"
 #include "media/tuner.h"
 #include <media/v4l2-common.h>
 
@@ -340,7 +341,7 @@ static struct i2c_algorithm au0828_i2c_algo_template = {
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_adapter au0828_i2c_adap_template = {
-	.name              = DRIVER_NAME,
+	.name              = KBUILD_MODNAME,
 	.owner             = THIS_MODULE,
 	.algo              = &au0828_i2c_algo_template,
 };
@@ -365,7 +366,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
 		rc = i2c_master_recv(c, &buf, 0);
 		if (rc < 0)
 			continue;
-		printk(KERN_INFO "%s: i2c scan: found device @ 0x%x  [%s]\n",
+		pr_info("%s: i2c scan: found device @ 0x%x  [%s]\n",
 		       name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
 	}
 }
@@ -381,7 +382,7 @@ int au0828_i2c_register(struct au0828_dev *dev)
 
 	dev->i2c_adap.dev.parent = &dev->usbdev->dev;
 
-	strlcpy(dev->i2c_adap.name, DRIVER_NAME,
+	strlcpy(dev->i2c_adap.name, KBUILD_MODNAME,
 		sizeof(dev->i2c_adap.name));
 
 	dev->i2c_adap.algo = &dev->i2c_algo;
@@ -396,11 +397,11 @@ int au0828_i2c_register(struct au0828_dev *dev)
 	dev->i2c_client.adapter = &dev->i2c_adap;
 
 	if (0 == dev->i2c_rc) {
-		printk(KERN_INFO "%s: i2c bus registered\n", DRIVER_NAME);
+		pr_info("i2c bus registered\n");
 		if (i2c_scan)
-			do_i2c_scan(DRIVER_NAME, &dev->i2c_client);
+			do_i2c_scan(KBUILD_MODNAME, &dev->i2c_client);
 	} else
-		printk(KERN_INFO "%s: i2c bus register FAILED\n", DRIVER_NAME);
+		pr_info("i2c bus register FAILED\n");
 
 	return dev->i2c_rc;
 }
diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c
index 5efb83977f39..6db1ce8e09e1 100644
--- a/drivers/media/usb/au0828/au0828-input.c
+++ b/drivers/media/usb/au0828/au0828-input.c
@@ -17,6 +17,8 @@
   GNU General Public License for more details.
  */
 
+#include "au0828.h"
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/delay.h>
@@ -29,8 +31,6 @@ static int disable_ir;
 module_param(disable_ir,        int, 0444);
 MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
 
-#include "au0828.h"
-
 struct au0828_rc {
 	struct au0828_dev *dev;
 	struct rc_dev *rc;
diff --git a/drivers/media/usb/au0828/au0828-vbi.c b/drivers/media/usb/au0828/au0828-vbi.c
index 63f593070ee8..932d24f42b24 100644
--- a/drivers/media/usb/au0828/au0828-vbi.c
+++ b/drivers/media/usb/au0828/au0828-vbi.c
@@ -21,13 +21,13 @@
    02110-1301, USA.
  */
 
+#include "au0828.h"
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 
-#include "au0828.h"
-
 static unsigned int vbibufs = 5;
 module_param(vbibufs, int, 0644);
 MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32");
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 574a08c7013d..193b2e364266 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -28,6 +28,8 @@
  *
  */
 
+#include "au0828.h"
+
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/init.h>
@@ -36,7 +38,6 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-event.h>
 #include <media/tuner.h>
-#include "au0828.h"
 #include "au0828-reg.h"
 
 static DEFINE_MUTEX(au0828_sysfs_lock);
@@ -52,7 +53,7 @@ MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
 #define au0828_isocdbg(fmt, arg...) \
 do {\
 	if (isoc_debug) { \
-		printk(KERN_INFO "au0828 %s :"fmt, \
+		pr_info("au0828 %s :"fmt, \
 		       __func__ , ##arg);	   \
 	} \
   } while (0)
@@ -105,12 +106,12 @@ static inline void print_err_status(struct au0828_dev *dev,
 static int check_dev(struct au0828_dev *dev)
 {
 	if (dev->dev_state & DEV_DISCONNECTED) {
-		printk(KERN_INFO "v4l2 ioctl: device not present\n");
+		pr_info("v4l2 ioctl: device not present\n");
 		return -ENODEV;
 	}
 
 	if (dev->dev_state & DEV_MISCONFIGURED) {
-		printk(KERN_INFO "v4l2 ioctl: device is misconfigured; "
+		pr_info("v4l2 ioctl: device is misconfigured; "
 		       "close and open it again\n");
 		return -EIO;
 	}
@@ -719,7 +720,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
 	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
 		rc = videobuf_iolock(vq, &buf->vb, NULL);
 		if (rc < 0) {
-			printk(KERN_INFO "videobuf_iolock failed\n");
+			pr_info("videobuf_iolock failed\n");
 			goto fail;
 		}
 	}
@@ -732,7 +733,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
 				      AU0828_MAX_ISO_BUFS, dev->max_pkt_size,
 				      au0828_isoc_copy);
 		if (rc < 0) {
-			printk(KERN_INFO "au0828_init_isoc failed\n");
+			pr_info("au0828_init_isoc failed\n");
 			goto fail;
 		}
 	}
@@ -803,7 +804,7 @@ static int au0828_analog_stream_enable(struct au0828_dev *d)
 		/* set au0828 interface0 to AS5 here again */
 		ret = usb_set_interface(d->usbdev, 0, 5);
 		if (ret < 0) {
-			printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
+			pr_info("Au0828 can't set alt setting to 5!\n");
 			return -EBUSY;
 		}
 	}
@@ -1092,7 +1093,7 @@ static int au0828_v4l2_close(struct file *filp)
 		   USB bandwidth */
 		ret = usb_set_interface(dev->usbdev, 0, 0);
 		if (ret < 0)
-			printk(KERN_INFO "Au0828 can't set alternate to 0!\n");
+			pr_info("Au0828 can't set alternate to 0!\n");
 	}
 	mutex_unlock(&dev->lock);
 
@@ -1346,7 +1347,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 		return rc;
 
 	if (videobuf_queue_is_busy(&fh->vb_vidq)) {
-		printk(KERN_INFO "%s queue busy\n", __func__);
+		pr_info("%s queue busy\n", __func__);
 		rc = -EBUSY;
 		goto out;
 	}
@@ -1999,7 +2000,7 @@ int au0828_analog_register(struct au0828_dev *dev,
 	retval = usb_set_interface(dev->usbdev,
 			interface->cur_altsetting->desc.bInterfaceNumber, 5);
 	if (retval != 0) {
-		printk(KERN_INFO "Failure setting usb interface0 to as5\n");
+		pr_info("Failure setting usb interface0 to as5\n");
 		return retval;
 	}
 
@@ -2023,7 +2024,7 @@ int au0828_analog_register(struct au0828_dev *dev,
 		}
 	}
 	if (!(dev->isoc_in_endpointaddr)) {
-		printk(KERN_INFO "Could not locate isoc endpoint\n");
+		pr_info("Could not locate isoc endpoint\n");
 		kfree(dev);
 		return -ENODEV;
 	}
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index 0d8cfe5cd264..d187129b96b7 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -19,6 +19,8 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/usb.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
@@ -42,7 +44,6 @@
 #include "au0828-reg.h"
 #include "au0828-cards.h"
 
-#define DRIVER_NAME "au0828"
 #define URB_COUNT   16
 #define URB_BUFSIZE (0xe522)
 
@@ -331,7 +332,7 @@ extern struct videobuf_queue_ops au0828_vbi_qops;
 
 #define dprintk(level, fmt, arg...)\
 	do { if (au0828_debug & level)\
-		printk(KERN_DEBUG DRIVER_NAME "/0: " fmt, ## arg);\
+		printk(KERN_DEBUG pr_fmt(fmt), ## arg);\
 	} while (0)
 
 /* au0828-input.c */
-- 
1.9.3


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

* [PATCH v2 12/18] [media] au0828: add pr_info to track au0828 suspend/resume code
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
                   ` (10 preceding siblings ...)
  2014-08-10  0:47 ` [PATCH v2 11/18] [media] au0828: use pr_foo macros Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 13/18] [media] dvb-frontend: add core support for tuner suspend/resume Mauro Carvalho Chehab
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

Suspend/resume conditions can be very tricky. Add some info
printk's to help tracking what's happening there.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c  | 4 ++++
 drivers/media/usb/au0828/au0828-dvb.c   | 4 ++++
 drivers/media/usb/au0828/au0828-input.c | 4 ++++
 drivers/media/usb/au0828/au0828-video.c | 5 +++++
 4 files changed, 17 insertions(+)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 452d14249348..bc064803b6c7 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -288,6 +288,8 @@ static int au0828_suspend(struct usb_interface *interface,
 	if (!dev)
 		return 0;
 
+	pr_info("Suspend\n");
+
 	au0828_rc_suspend(dev);
 	au0828_v4l2_suspend(dev);
 	au0828_dvb_suspend(dev);
@@ -303,6 +305,8 @@ static int au0828_resume(struct usb_interface *interface)
 	if (!dev)
 		return 0;
 
+	pr_info("Resume\n");
+
 	/* Power Up the bridge */
 	au0828_write(dev, REG_600, 1 << 4);
 
diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c
index 99cf83bca033..ee45990c0be1 100644
--- a/drivers/media/usb/au0828/au0828-dvb.c
+++ b/drivers/media/usb/au0828/au0828-dvb.c
@@ -619,6 +619,8 @@ void au0828_dvb_suspend(struct au0828_dev *dev)
 	struct au0828_dvb *dvb = &dev->dvb;
 
 	if (dvb && dev->urb_streaming) {
+		pr_info("stopping DVB\n");
+
 		cancel_work_sync(&dev->restart_streaming);
 
 		/* Stop transport */
@@ -634,6 +636,8 @@ void au0828_dvb_resume(struct au0828_dev *dev)
 	struct au0828_dvb *dvb = &dev->dvb;
 
 	if (dvb && dev->urb_streaming) {
+		pr_info("resuming DVB\n");
+
 		au0828_set_frontend(dvb->frontend);
 
 		/* Start transport */
diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c
index 6db1ce8e09e1..63995f97dc65 100644
--- a/drivers/media/usb/au0828/au0828-input.c
+++ b/drivers/media/usb/au0828/au0828-input.c
@@ -378,6 +378,8 @@ int au0828_rc_suspend(struct au0828_dev *dev)
 	if (!ir)
 		return 0;
 
+	pr_info("Stopping RC\n");
+
 	cancel_delayed_work_sync(&ir->work);
 
 	/* Disable IR */
@@ -393,6 +395,8 @@ int au0828_rc_resume(struct au0828_dev *dev)
 	if (!ir)
 		return 0;
 
+	pr_info("Restarting RC\n");
+
 	/* Enable IR */
 	au8522_rc_set(ir, 0xe0, 1 << 4);
 
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 193b2e364266..5f337b118bff 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -1876,7 +1876,10 @@ void au0828_v4l2_suspend(struct au0828_dev *dev)
 	struct urb *urb;
 	int i;
 
+	pr_info("stopping V4L2\n");
+
 	if (dev->stream_state == STREAM_ON) {
+		pr_info("stopping V4L2 active URBs\n");
 		au0828_analog_stream_disable(dev);
 		/* stop urbs */
 		for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
@@ -1900,6 +1903,8 @@ void au0828_v4l2_resume(struct au0828_dev *dev)
 {
 	int i, rc;
 
+	pr_info("restarting V4L2\n");
+
 	if (dev->stream_state == STREAM_ON) {
 		au0828_stream_interrupt(dev);
 		au0828_init_tuner(dev);
-- 
1.9.3


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

* [PATCH v2 13/18] [media] dvb-frontend: add core support for tuner suspend/resume
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
                   ` (11 preceding siblings ...)
  2014-08-10  0:47 ` [PATCH v2 12/18] [media] au0828: add pr_info to track au0828 suspend/resume code Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 14/18] [media] xc5000: fix xc5000 suspend Mauro Carvalho Chehab
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

While several tuners have some sort of suspend/resume
implementation, this is currently mangled with an optional
.sleep callback that it is also used to put the device on
low power mode.

Not all drivers implement it, as returning the driver from
low power may require to re-load the firmware, with takes
some time. Also, some drivers may delay it.

So, the more coherent is to add two new optional callbacks
that will let the tuners to directy implement suspend and
resume callbacks if they need.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/dvb-core/dvb_frontend.c | 8 ++++++--
 drivers/media/dvb-core/dvb_frontend.h | 2 ++
 drivers/media/v4l2-core/tuner-core.c  | 8 ++++++--
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index c2a6a0a85813..a5810391af61 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -2550,7 +2550,9 @@ int dvb_frontend_suspend(struct dvb_frontend *fe)
 	dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num,
 			fe->id);
 
-	if (fe->ops.tuner_ops.sleep)
+	if (fe->ops.tuner_ops.suspend)
+		ret = fe->ops.tuner_ops.suspend(fe);
+	else if (fe->ops.tuner_ops.sleep)
 		ret = fe->ops.tuner_ops.sleep(fe);
 
 	if (fe->ops.sleep)
@@ -2572,7 +2574,9 @@ int dvb_frontend_resume(struct dvb_frontend *fe)
 	if (fe->ops.init)
 		ret = fe->ops.init(fe);
 
-	if (fe->ops.tuner_ops.init)
+	if (fe->ops.tuner_ops.resume)
+		ret = fe->ops.tuner_ops.resume(fe);
+	else if (fe->ops.tuner_ops.init)
 		ret = fe->ops.tuner_ops.init(fe);
 
 	fe->exit = DVB_FE_NO_EXIT;
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index d398de4b6ef4..816269e5f706 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -201,6 +201,8 @@ struct dvb_tuner_ops {
 	int (*release)(struct dvb_frontend *fe);
 	int (*init)(struct dvb_frontend *fe);
 	int (*sleep)(struct dvb_frontend *fe);
+	int (*suspend)(struct dvb_frontend *fe);
+	int (*resume)(struct dvb_frontend *fe);
 
 	/** This is for simple PLLs - set all parameters in one go. */
 	int (*set_params)(struct dvb_frontend *fe);
diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c
index 06c18ba16fa0..177023200737 100644
--- a/drivers/media/v4l2-core/tuner-core.c
+++ b/drivers/media/v4l2-core/tuner-core.c
@@ -1260,7 +1260,9 @@ static int tuner_suspend(struct device *dev)
 
 	tuner_dbg("suspend\n");
 
-	if (!t->standby && analog_ops->standby)
+	if (t->fe.ops.tuner_ops.suspend)
+		t->fe.ops.tuner_ops.suspend(&t->fe);
+	else if (!t->standby && analog_ops->standby)
 		analog_ops->standby(&t->fe);
 
 	return 0;
@@ -1273,7 +1275,9 @@ static int tuner_resume(struct device *dev)
 
 	tuner_dbg("resume\n");
 
-	if (!t->standby)
+	if (t->fe.ops.tuner_ops.resume)
+		t->fe.ops.tuner_ops.resume(&t->fe);
+	else if (!t->standby)
 		if (set_mode(t, t->mode) == 0)
 			set_freq(t, 0);
 
-- 
1.9.3


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

* [PATCH v2 14/18] [media] xc5000: fix xc5000 suspend
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
                   ` (12 preceding siblings ...)
  2014-08-10  0:47 ` [PATCH v2 13/18] [media] dvb-frontend: add core support for tuner suspend/resume Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 15/18] [media] au0828: move the code that sets DTV on a separate function Mauro Carvalho Chehab
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

After xc5000 stops working, it waits for 5 seconds, waiting
for a new usage. Only after that it goes to low power mode.

If a suspend event happens before that, a work queue will
remain active, with causes suspend to crash.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/tuners/xc5000.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index e135760f7d48..af137046bfe5 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -1229,6 +1229,24 @@ static int xc5000_sleep(struct dvb_frontend *fe)
 	return 0;
 }
 
+static int xc5000_suspend(struct dvb_frontend *fe)
+{
+	struct xc5000_priv *priv = fe->tuner_priv;
+	int ret;
+
+	dprintk(1, "%s()\n", __func__);
+
+	cancel_delayed_work(&priv->timer_sleep);
+
+	ret = xc5000_tuner_reset(fe);
+	if (ret != 0)
+		printk(KERN_ERR
+			"xc5000: %s() unable to shutdown tuner\n",
+			__func__);
+
+	return 0;
+}
+
 static int xc5000_init(struct dvb_frontend *fe)
 {
 	struct xc5000_priv *priv = fe->tuner_priv;
@@ -1293,6 +1311,7 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = {
 	.release	   = xc5000_release,
 	.init		   = xc5000_init,
 	.sleep		   = xc5000_sleep,
+	.suspend	   = xc5000_suspend,
 
 	.set_config	   = xc5000_set_config,
 	.set_params	   = xc5000_set_params,
-- 
1.9.3


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

* [PATCH v2 15/18] [media] au0828: move the code that sets DTV on a separate function
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
                   ` (13 preceding siblings ...)
  2014-08-10  0:47 ` [PATCH v2 14/18] [media] xc5000: fix xc5000 suspend Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 16/18] [media] xc5000: Split config and set code for analog/radio Mauro Carvalho Chehab
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

As we'll be adding a code to resume tuner operation, we
need to move the code that actually sets DTV on a separate
function, to be called by the resume code.

No functional changes, just code got moved.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/tuners/xc5000.c | 79 ++++++++++++++++++++++++-------------------
 1 file changed, 45 insertions(+), 34 deletions(-)

diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index af137046bfe5..3293fd8df59b 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -59,6 +59,7 @@ struct xc5000_priv {
 	u32 freq_hz, freq_offset;
 	u32 bandwidth;
 	u8  video_standard;
+	unsigned int mode;
 	u8  rf_mode;
 	u8  radio_input;
 
@@ -712,9 +713,50 @@ static void xc_debug_dump(struct xc5000_priv *priv)
 	}
 }
 
+static int xc5000_tune_digital(struct dvb_frontend *fe)
+{
+	struct xc5000_priv *priv = fe->tuner_priv;
+	int ret;
+	u32 bw = fe->dtv_property_cache.bandwidth_hz;
+
+	ret = xc_set_signal_source(priv, priv->rf_mode);
+	if (ret != 0) {
+		printk(KERN_ERR
+			"xc5000: xc_set_signal_source(%d) failed\n",
+			priv->rf_mode);
+		return -EREMOTEIO;
+	}
+
+	ret = xc_set_tv_standard(priv,
+		xc5000_standard[priv->video_standard].video_mode,
+		xc5000_standard[priv->video_standard].audio_mode, 0);
+	if (ret != 0) {
+		printk(KERN_ERR "xc5000: xc_set_tv_standard failed\n");
+		return -EREMOTEIO;
+	}
+
+	ret = xc_set_IF_frequency(priv, priv->if_khz);
+	if (ret != 0) {
+		printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n",
+		       priv->if_khz);
+		return -EIO;
+	}
+
+	xc_write_reg(priv, XREG_OUTPUT_AMP, 0x8a);
+
+	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
+
+	if (debug)
+		xc_debug_dump(priv);
+
+	priv->bandwidth = bw;
+
+	return 0;
+}
+
 static int xc5000_set_params(struct dvb_frontend *fe)
 {
-	int ret, b;
+	int b;
 	struct xc5000_priv *priv = fe->tuner_priv;
 	u32 bw = fe->dtv_property_cache.bandwidth_hz;
 	u32 freq = fe->dtv_property_cache.frequency;
@@ -794,43 +836,12 @@ static int xc5000_set_params(struct dvb_frontend *fe)
 	}
 
 	priv->freq_hz = freq - priv->freq_offset;
+	priv->mode = V4L2_TUNER_DIGITAL_TV;
 
 	dprintk(1, "%s() frequency=%d (compensated to %d)\n",
 		__func__, freq, priv->freq_hz);
 
-	ret = xc_set_signal_source(priv, priv->rf_mode);
-	if (ret != 0) {
-		printk(KERN_ERR
-			"xc5000: xc_set_signal_source(%d) failed\n",
-			priv->rf_mode);
-		return -EREMOTEIO;
-	}
-
-	ret = xc_set_tv_standard(priv,
-		xc5000_standard[priv->video_standard].video_mode,
-		xc5000_standard[priv->video_standard].audio_mode, 0);
-	if (ret != 0) {
-		printk(KERN_ERR "xc5000: xc_set_tv_standard failed\n");
-		return -EREMOTEIO;
-	}
-
-	ret = xc_set_IF_frequency(priv, priv->if_khz);
-	if (ret != 0) {
-		printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n",
-		       priv->if_khz);
-		return -EIO;
-	}
-
-	xc_write_reg(priv, XREG_OUTPUT_AMP, 0x8a);
-
-	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
-
-	if (debug)
-		xc_debug_dump(priv);
-
-	priv->bandwidth = bw;
-
-	return 0;
+	return xc5000_tune_digital(fe);
 }
 
 static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
-- 
1.9.3


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

* [PATCH v2 16/18] [media] xc5000: Split config and set code for analog/radio
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
                   ` (14 preceding siblings ...)
  2014-08-10  0:47 ` [PATCH v2 15/18] [media] au0828: move the code that sets DTV on a separate function Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 17/18] [media] xc5000: add a resume function Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 18/18] [media] xc5000: better name the functions Mauro Carvalho Chehab
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

As we need a function that reapply the last tuned radio,
in order to do resume, split the code that validates and
updates the internal priv struct from the ones that
actually set radio and TV.

A latter patch will add support for resume.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/tuners/xc5000.c | 81 ++++++++++++++++++++++++++++++-------------
 1 file changed, 56 insertions(+), 25 deletions(-)

diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index 3293fd8df59b..78695ed4549c 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -863,12 +863,10 @@ static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
 	return ret;
 }
 
-static int xc5000_set_tv_freq(struct dvb_frontend *fe,
-	struct analog_parameters *params)
+static void xc5000_config_tv(struct dvb_frontend *fe,
+			     struct analog_parameters *params)
 {
 	struct xc5000_priv *priv = fe->tuner_priv;
-	u16 pll_lock_status;
-	int ret;
 
 	dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
 		__func__, params->frequency);
@@ -887,42 +885,49 @@ static int xc5000_set_tv_freq(struct dvb_frontend *fe,
 	if (params->std & V4L2_STD_MN) {
 		/* default to BTSC audio standard */
 		priv->video_standard = MN_NTSC_PAL_BTSC;
-		goto tune_channel;
+		return;
 	}
 
 	if (params->std & V4L2_STD_PAL_BG) {
 		/* default to NICAM audio standard */
 		priv->video_standard = BG_PAL_NICAM;
-		goto tune_channel;
+		return;
 	}
 
 	if (params->std & V4L2_STD_PAL_I) {
 		/* default to NICAM audio standard */
 		priv->video_standard = I_PAL_NICAM;
-		goto tune_channel;
+		return;
 	}
 
 	if (params->std & V4L2_STD_PAL_DK) {
 		/* default to NICAM audio standard */
 		priv->video_standard = DK_PAL_NICAM;
-		goto tune_channel;
+		return;
 	}
 
 	if (params->std & V4L2_STD_SECAM_DK) {
 		/* default to A2 DK1 audio standard */
 		priv->video_standard = DK_SECAM_A2DK1;
-		goto tune_channel;
+		return;
 	}
 
 	if (params->std & V4L2_STD_SECAM_L) {
 		priv->video_standard = L_SECAM_NICAM;
-		goto tune_channel;
+		return;
 	}
 
 	if (params->std & V4L2_STD_SECAM_LC) {
 		priv->video_standard = LC_SECAM_NICAM;
-		goto tune_channel;
+		return;
 	}
+}
+
+static int xc5000_set_tv_freq(struct dvb_frontend *fe)
+{
+	struct xc5000_priv *priv = fe->tuner_priv;
+	u16 pll_lock_status;
+	int ret;
 
 tune_channel:
 	ret = xc_set_signal_source(priv, priv->rf_mode);
@@ -966,12 +971,11 @@ tune_channel:
 	return 0;
 }
 
-static int xc5000_set_radio_freq(struct dvb_frontend *fe,
-	struct analog_parameters *params)
+static int xc5000_config_radio(struct dvb_frontend *fe,
+			       struct analog_parameters *params)
+
 {
 	struct xc5000_priv *priv = fe->tuner_priv;
-	int ret = -EINVAL;
-	u8 radio_input;
 
 	dprintk(1, "%s() frequency=%d (in units of khz)\n",
 		__func__, params->frequency);
@@ -981,6 +985,18 @@ static int xc5000_set_radio_freq(struct dvb_frontend *fe,
 		return -EINVAL;
 	}
 
+	priv->freq_hz = params->frequency * 125 / 2;
+	priv->rf_mode = XC_RF_MODE_AIR;
+
+	return 0;
+}
+
+static int xc5000_set_radio_freq(struct dvb_frontend *fe)
+{
+	struct xc5000_priv *priv = fe->tuner_priv;
+	int ret;
+	u8 radio_input;
+
 	if (priv->radio_input == XC5000_RADIO_FM1)
 		radio_input = FM_RADIO_INPUT1;
 	else if  (priv->radio_input == XC5000_RADIO_FM2)
@@ -993,10 +1009,6 @@ static int xc5000_set_radio_freq(struct dvb_frontend *fe,
 		return -EINVAL;
 	}
 
-	priv->freq_hz = params->frequency * 125 / 2;
-
-	priv->rf_mode = XC_RF_MODE_AIR;
-
 	ret = xc_set_tv_standard(priv, xc5000_standard[radio_input].video_mode,
 			       xc5000_standard[radio_input].audio_mode, radio_input);
 
@@ -1024,11 +1036,27 @@ static int xc5000_set_radio_freq(struct dvb_frontend *fe,
 	return 0;
 }
 
+static int xc5000_apply_params(struct dvb_frontend *fe)
+{
+	struct xc5000_priv *priv = fe->tuner_priv;
+
+	switch (priv->mode) {
+	case V4L2_TUNER_RADIO:
+		return xc5000_set_radio_freq(fe);
+	case V4L2_TUNER_ANALOG_TV:
+		return xc5000_set_tv_freq(fe);
+	case V4L2_TUNER_DIGITAL_TV:
+		return xc5000_tune_digital(fe);
+	}
+
+	return 0;
+}
+
 static int xc5000_set_analog_params(struct dvb_frontend *fe,
 			     struct analog_parameters *params)
 {
 	struct xc5000_priv *priv = fe->tuner_priv;
-	int ret = -EINVAL;
+	int ret;
 
 	if (priv->i2c_props.adap == NULL)
 		return -EINVAL;
@@ -1040,18 +1068,21 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe,
 
 	switch (params->mode) {
 	case V4L2_TUNER_RADIO:
-		ret = xc5000_set_radio_freq(fe, params);
+		ret = xc5000_config_radio(fe, params);
+		if (ret)
+			return ret;
 		break;
 	case V4L2_TUNER_ANALOG_TV:
-	case V4L2_TUNER_DIGITAL_TV:
-		ret = xc5000_set_tv_freq(fe, params);
+		xc5000_config_tv(fe, params);
+		break;
+	default:
 		break;
 	}
+	priv->mode = params->mode;
 
-	return ret;
+	return xc5000_apply_params(fe);
 }
 
-
 static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
 {
 	struct xc5000_priv *priv = fe->tuner_priv;
-- 
1.9.3


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

* [PATCH v2 17/18] [media] xc5000: add a resume function
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
                   ` (15 preceding siblings ...)
  2014-08-10  0:47 ` [PATCH v2 16/18] [media] xc5000: Split config and set code for analog/radio Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  2014-08-10  0:47 ` [PATCH v2 18/18] [media] xc5000: better name the functions Mauro Carvalho Chehab
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

If a device suspends/hibertates with a station tuned, restore
the tuner station at resume.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/tuners/xc5000.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index 78695ed4549c..140c537bcfcc 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -1354,6 +1354,7 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = {
 	.init		   = xc5000_init,
 	.sleep		   = xc5000_sleep,
 	.suspend	   = xc5000_suspend,
+	.resume		   = xc5000_apply_params,
 
 	.set_config	   = xc5000_set_config,
 	.set_params	   = xc5000_set_params,
-- 
1.9.3


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

* [PATCH v2 18/18] [media] xc5000: better name the functions
  2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
                   ` (16 preceding siblings ...)
  2014-08-10  0:47 ` [PATCH v2 17/18] [media] xc5000: add a resume function Mauro Carvalho Chehab
@ 2014-08-10  0:47 ` Mauro Carvalho Chehab
  17 siblings, 0 replies; 19+ messages in thread
From: Mauro Carvalho Chehab @ 2014-08-10  0:47 UTC (permalink / raw)
  Cc: Shuah Khan, Mauro Carvalho Chehab, Linux Media Mailing List,
	Mauro Carvalho Chehab

xc5000_set_params() is a bad name for a function that
handles only digital TV. Rename it to xc5000_set_digital_params(),
and proper name the generic function that works for both
digital and analog.

No functional changes.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/tuners/xc5000.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index 140c537bcfcc..c1905784b08e 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -754,7 +754,7 @@ static int xc5000_tune_digital(struct dvb_frontend *fe)
 	return 0;
 }
 
-static int xc5000_set_params(struct dvb_frontend *fe)
+static int xc5000_set_digital_params(struct dvb_frontend *fe)
 {
 	int b;
 	struct xc5000_priv *priv = fe->tuner_priv;
@@ -1036,7 +1036,7 @@ static int xc5000_set_radio_freq(struct dvb_frontend *fe)
 	return 0;
 }
 
-static int xc5000_apply_params(struct dvb_frontend *fe)
+static int xc5000_set_params(struct dvb_frontend *fe)
 {
 	struct xc5000_priv *priv = fe->tuner_priv;
 
@@ -1080,7 +1080,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe,
 	}
 	priv->mode = params->mode;
 
-	return xc5000_apply_params(fe);
+	return xc5000_set_params(fe);
 }
 
 static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
@@ -1354,10 +1354,10 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = {
 	.init		   = xc5000_init,
 	.sleep		   = xc5000_sleep,
 	.suspend	   = xc5000_suspend,
-	.resume		   = xc5000_apply_params,
+	.resume		   = xc5000_set_params,
 
 	.set_config	   = xc5000_set_config,
-	.set_params	   = xc5000_set_params,
+	.set_params	   = xc5000_set_digital_params,
 	.set_analog_params = xc5000_set_analog_params,
 	.get_frequency	   = xc5000_get_frequency,
 	.get_if_frequency  = xc5000_get_if_frequency,
-- 
1.9.3


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

end of thread, other threads:[~2014-08-10  0:47 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-10  0:47 [PATCH v2 00/18] au0828: Fix suspend/resume Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 01/18] [media] au0828: avoid race conditions at RC stop Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 02/18] [media] au0828: handle IR int during suspend/resume Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 03/18] [media] au0828: add au0828_rc_*() stubs for VIDEO_AU0828_RC disabled case Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 04/18] [media] au0828: remove CONFIG_VIDEO_AU0828_RC scope around au0828_rc_*() Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 05/18] [media] au0828: don't let the IR polling thread to run at suspend Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 06/18] [media] au0828: be sure to reenable the bridge and GPIOs on resume Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 07/18] [media] au0828: Add suspend code for DVB Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 08/18] [media] au0828: properly handle stream on/off state Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 09/18] [media] au0828: add suspend/resume code for V4L2 Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 10/18] [media] au0828: Remove a bad whitespace Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 11/18] [media] au0828: use pr_foo macros Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 12/18] [media] au0828: add pr_info to track au0828 suspend/resume code Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 13/18] [media] dvb-frontend: add core support for tuner suspend/resume Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 14/18] [media] xc5000: fix xc5000 suspend Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 15/18] [media] au0828: move the code that sets DTV on a separate function Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 16/18] [media] xc5000: Split config and set code for analog/radio Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 17/18] [media] xc5000: add a resume function Mauro Carvalho Chehab
2014-08-10  0:47 ` [PATCH v2 18/18] [media] xc5000: better name the functions Mauro Carvalho Chehab

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.