diff options
| author | Jinyoung Park <jinyoungp@nvidia.com> | 2017-08-29 04:40:10 -0400 |
|---|---|---|
| committer | Mudit Jain <muditj@nvidia.com> | 2018-07-13 06:41:37 -0400 |
| commit | 53c39efa3117316ddcb66ffceaab8d1e2b2c1d80 (patch) | |
| tree | 72ee07be59bd17e7686f54ab4087fdcfa9da5985 /drivers | |
| parent | 1354da1e051aa5d2163cae3dd213f48dbd236ee3 (diff) | |
i2c: busses: i2c-tegra-hv: Add suspend/resume handler
In suspend handler, it blocks i2c transfer, disables irq and waits for
the work to finish.
In resume handler, it enables irq and unblocks i2c transfer.
STR-390
Change-Id: I8244bb8f00fba4bbb48e4caa43123c964b8e29a3
Signed-off-by: Jinyoung Park <jinyoungp@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1547599
Reviewed-by: Vishal Annapurve <vannapurve@nvidia.com>
Reviewed-by: Nitin Sehgal <nsehgal@nvidia.com>
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Kurt Yi <kyi@nvidia.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/i2c/busses/i2c-tegra-hv-common.c | 16 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-tegra-hv-common.h | 4 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-tegra-hv.c | 33 |
3 files changed, 48 insertions, 5 deletions
diff --git a/drivers/i2c/busses/i2c-tegra-hv-common.c b/drivers/i2c/busses/i2c-tegra-hv-common.c index cb89e4063..51338e2a6 100644 --- a/drivers/i2c/busses/i2c-tegra-hv-common.c +++ b/drivers/i2c/busses/i2c-tegra-hv-common.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * IVC based Library for I2C services. | 2 | * IVC based Library for I2C services. |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. | 4 | * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
| 7 | * under the terms and conditions of the GNU General Public License, | 7 | * under the terms and conditions of the GNU General Public License, |
| @@ -295,12 +295,24 @@ void hv_i2c_comm_chan_free(struct tegra_hv_i2c_comm_chan *comm_chan) | |||
| 295 | 295 | ||
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | void hv_i2c_comm_suspend(struct tegra_hv_i2c_comm_chan *comm_chan) | ||
| 299 | { | ||
| 300 | disable_irq(comm_chan->ivck->irq); | ||
| 301 | cancel_work_sync(&comm_chan->hv_comm_dev->work); | ||
| 302 | } | ||
| 303 | |||
| 304 | void hv_i2c_comm_resume(struct tegra_hv_i2c_comm_chan *comm_chan) | ||
| 305 | { | ||
| 306 | enable_irq(comm_chan->ivck->irq); | ||
| 307 | schedule_work(&comm_chan->hv_comm_dev->work); | ||
| 308 | } | ||
| 309 | |||
| 298 | static irqreturn_t hv_i2c_isr(int irq, void *dev_id) | 310 | static irqreturn_t hv_i2c_isr(int irq, void *dev_id) |
| 299 | { | 311 | { |
| 300 | struct tegra_hv_i2c_comm_dev *comm_dev = | 312 | struct tegra_hv_i2c_comm_dev *comm_dev = |
| 301 | (struct tegra_hv_i2c_comm_dev *)dev_id; | 313 | (struct tegra_hv_i2c_comm_dev *)dev_id; |
| 302 | 314 | ||
| 303 | queue_work(system_wq, &comm_dev->work); | 315 | schedule_work(&comm_dev->work); |
| 304 | 316 | ||
| 305 | return IRQ_HANDLED; | 317 | return IRQ_HANDLED; |
| 306 | } | 318 | } |
diff --git a/drivers/i2c/busses/i2c-tegra-hv-common.h b/drivers/i2c/busses/i2c-tegra-hv-common.h index 9db5565fa..cc64efc85 100644 --- a/drivers/i2c/busses/i2c-tegra-hv-common.h +++ b/drivers/i2c/busses/i2c-tegra-hv-common.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. | 2 | * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. |
| 3 | * | 3 | * |
| 4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
| 5 | * under the terms and conditions of the GNU General Public License, | 5 | * under the terms and conditions of the GNU General Public License, |
| @@ -33,6 +33,8 @@ int hv_i2c_get_max_payload(struct tegra_hv_i2c_comm_chan *comm_chan, | |||
| 33 | int hv_i2c_comm_chan_cleanup(struct tegra_hv_i2c_comm_chan *comm_chan, | 33 | int hv_i2c_comm_chan_cleanup(struct tegra_hv_i2c_comm_chan *comm_chan, |
| 34 | phys_addr_t base); | 34 | phys_addr_t base); |
| 35 | void hv_i2c_comm_chan_free(struct tegra_hv_i2c_comm_chan *comm_chan); | 35 | void hv_i2c_comm_chan_free(struct tegra_hv_i2c_comm_chan *comm_chan); |
| 36 | void hv_i2c_comm_suspend(struct tegra_hv_i2c_comm_chan *comm_chan); | ||
| 37 | void hv_i2c_comm_resume(struct tegra_hv_i2c_comm_chan *comm_chan); | ||
| 36 | void *hv_i2c_comm_init(struct device *dev, i2c_isr_handler handler, | 38 | void *hv_i2c_comm_init(struct device *dev, i2c_isr_handler handler, |
| 37 | void *data); | 39 | void *data); |
| 38 | void tegra_hv_i2c_poll_cleanup(struct tegra_hv_i2c_comm_chan *comm_chan); | 40 | void tegra_hv_i2c_poll_cleanup(struct tegra_hv_i2c_comm_chan *comm_chan); |
diff --git a/drivers/i2c/busses/i2c-tegra-hv.c b/drivers/i2c/busses/i2c-tegra-hv.c index da0092d03..d7ef1110b 100644 --- a/drivers/i2c/busses/i2c-tegra-hv.c +++ b/drivers/i2c/busses/i2c-tegra-hv.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * drivers/i2c/busses/i2c-tegra-hv.c | 2 | * drivers/i2c/busses/i2c-tegra-hv.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2015-2016 NVIDIA Corporation. All rights reserved. | 4 | * Copyright (C) 2015-2017 NVIDIA Corporation. All rights reserved. |
| 5 | * Author: Arnab Basu <abasu@nvidia.com> | 5 | * Author: Arnab Basu <abasu@nvidia.com> |
| 6 | * | 6 | * |
| 7 | * This software is licensed under the terms of the GNU General Public | 7 | * This software is licensed under the terms of the GNU General Public |
| @@ -337,6 +337,33 @@ static void tegra_hv_i2c_shutdown(struct platform_device *pdev) | |||
| 337 | i2c_shutdown_adapter(&i2c_dev->adapter); | 337 | i2c_shutdown_adapter(&i2c_dev->adapter); |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | #ifdef CONFIG_PM_SLEEP | ||
| 341 | static int tegra_hv_i2c_suspend(struct device *dev) | ||
| 342 | { | ||
| 343 | struct tegra_hv_i2c_dev *i2c_dev = dev_get_drvdata(dev); | ||
| 344 | |||
| 345 | i2c_shutdown_adapter(&i2c_dev->adapter); | ||
| 346 | hv_i2c_comm_suspend(i2c_dev->comm_chan); | ||
| 347 | |||
| 348 | return 0; | ||
| 349 | } | ||
| 350 | |||
| 351 | static int tegra_hv_i2c_resume(struct device *dev) | ||
| 352 | { | ||
| 353 | struct tegra_hv_i2c_dev *i2c_dev = dev_get_drvdata(dev); | ||
| 354 | |||
| 355 | hv_i2c_comm_resume(i2c_dev->comm_chan); | ||
| 356 | i2c_shutdown_clear_adapter(&i2c_dev->adapter); | ||
| 357 | |||
| 358 | return 0; | ||
| 359 | } | ||
| 360 | |||
| 361 | static const struct dev_pm_ops tegra_hv_i2c_pm_ops = { | ||
| 362 | .suspend_noirq = tegra_hv_i2c_suspend, | ||
| 363 | .resume_noirq = tegra_hv_i2c_resume, | ||
| 364 | }; | ||
| 365 | #endif /* CONFIG_PM_SLEEP */ | ||
| 366 | |||
| 340 | static struct platform_device_id tegra_hv_i2c_devtype[] = { | 367 | static struct platform_device_id tegra_hv_i2c_devtype[] = { |
| 341 | { | 368 | { |
| 342 | .name = "tegra12-hv-i2c", | 369 | .name = "tegra12-hv-i2c", |
| @@ -354,7 +381,9 @@ static struct platform_driver tegra_hv_i2c_driver = { | |||
| 354 | .name = "tegra-hv-i2c", | 381 | .name = "tegra-hv-i2c", |
| 355 | .owner = THIS_MODULE, | 382 | .owner = THIS_MODULE, |
| 356 | .of_match_table = of_match_ptr(tegra_hv_i2c_of_match), | 383 | .of_match_table = of_match_ptr(tegra_hv_i2c_of_match), |
| 357 | .pm = NULL, | 384 | #ifdef CONFIG_PM_SLEEP |
| 385 | .pm = &tegra_hv_i2c_pm_ops, | ||
| 386 | #endif | ||
| 358 | }, | 387 | }, |
| 359 | }; | 388 | }; |
| 360 | 389 | ||
