Commit 306df0b0 authored by Vaibhav Gupta's avatar Vaibhav Gupta Committed by Marc Kleine-Budde

can: pch_can: use generic power management

Drivers using legacy power management .suspen()/.resume() callbacks have to
manage PCI states and device's PM states themselves. They also need to take
care of standard configuration registers.

Switch to generic power management framework using a single "struct dev_pm_ops"
variable to take the unnecessary load from the driver. This also avoids the
need for the driver to directly call most of the PCI helper functions and
device power state control functions, as through the generic framework PCI Core
takes care of the necessary operations, and drivers are required to do only
device-specific jobs.
Signed-off-by: default avatarVaibhav Gupta <vaibhavgupta40@gmail.com>
Link: https://lore.kernel.org/r/20200728085757.888620-1-vaibhavgupta40@gmail.comSigned-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent b060585d
...@@ -957,8 +957,7 @@ static void pch_can_remove(struct pci_dev *pdev) ...@@ -957,8 +957,7 @@ static void pch_can_remove(struct pci_dev *pdev)
free_candev(priv->ndev); free_candev(priv->ndev);
} }
#ifdef CONFIG_PM static void __maybe_unused pch_can_set_int_custom(struct pch_can_priv *priv)
static void pch_can_set_int_custom(struct pch_can_priv *priv)
{ {
/* Clearing the IE, SIE and EIE bits of Can control register. */ /* Clearing the IE, SIE and EIE bits of Can control register. */
pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE); pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE);
...@@ -969,14 +968,14 @@ static void pch_can_set_int_custom(struct pch_can_priv *priv) ...@@ -969,14 +968,14 @@ static void pch_can_set_int_custom(struct pch_can_priv *priv)
} }
/* This function retrieves interrupt enabled for the CAN device. */ /* This function retrieves interrupt enabled for the CAN device. */
static u32 pch_can_get_int_enables(struct pch_can_priv *priv) static u32 __maybe_unused pch_can_get_int_enables(struct pch_can_priv *priv)
{ {
/* Obtaining the status of IE, SIE and EIE interrupt bits. */ /* Obtaining the status of IE, SIE and EIE interrupt bits. */
return (ioread32(&priv->regs->cont) & PCH_CTRL_IE_SIE_EIE) >> 1; return (ioread32(&priv->regs->cont) & PCH_CTRL_IE_SIE_EIE) >> 1;
} }
static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, static u32 __maybe_unused pch_can_get_rxtx_ir(struct pch_can_priv *priv,
enum pch_ifreg dir) u32 buff_num, enum pch_ifreg dir)
{ {
u32 ie, enable; u32 ie, enable;
...@@ -997,8 +996,8 @@ static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num, ...@@ -997,8 +996,8 @@ static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num,
return enable; return enable;
} }
static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv, static void __maybe_unused pch_can_set_rx_buffer_link(struct pch_can_priv *priv,
u32 buffer_num, int set) u32 buffer_num, int set)
{ {
iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask); iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask);
pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num); pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num);
...@@ -1013,7 +1012,8 @@ static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv, ...@@ -1013,7 +1012,8 @@ static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv,
pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num); pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num);
} }
static u32 pch_can_get_rx_buffer_link(struct pch_can_priv *priv, u32 buffer_num) static u32 __maybe_unused pch_can_get_rx_buffer_link(struct pch_can_priv *priv,
u32 buffer_num)
{ {
u32 link; u32 link;
...@@ -1027,20 +1027,19 @@ static u32 pch_can_get_rx_buffer_link(struct pch_can_priv *priv, u32 buffer_num) ...@@ -1027,20 +1027,19 @@ static u32 pch_can_get_rx_buffer_link(struct pch_can_priv *priv, u32 buffer_num)
return link; return link;
} }
static int pch_can_get_buffer_status(struct pch_can_priv *priv) static int __maybe_unused pch_can_get_buffer_status(struct pch_can_priv *priv)
{ {
return (ioread32(&priv->regs->treq1) & 0xffff) | return (ioread32(&priv->regs->treq1) & 0xffff) |
(ioread32(&priv->regs->treq2) << 16); (ioread32(&priv->regs->treq2) << 16);
} }
static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) static int __maybe_unused pch_can_suspend(struct device *dev_d)
{ {
int i; int i;
int retval;
u32 buf_stat; /* Variable for reading the transmit buffer status. */ u32 buf_stat; /* Variable for reading the transmit buffer status. */
int counter = PCH_COUNTER_LIMIT; int counter = PCH_COUNTER_LIMIT;
struct net_device *dev = pci_get_drvdata(pdev); struct net_device *dev = dev_get_drvdata(dev_d);
struct pch_can_priv *priv = netdev_priv(dev); struct pch_can_priv *priv = netdev_priv(dev);
/* Stop the CAN controller */ /* Stop the CAN controller */
...@@ -1058,7 +1057,7 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -1058,7 +1057,7 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state)
udelay(1); udelay(1);
} }
if (!counter) if (!counter)
dev_err(&pdev->dev, "%s -> Transmission time out.\n", __func__); dev_err(dev_d, "%s -> Transmission time out.\n", __func__);
/* Save interrupt configuration and then disable them */ /* Save interrupt configuration and then disable them */
priv->int_enables = pch_can_get_int_enables(priv); priv->int_enables = pch_can_get_int_enables(priv);
...@@ -1081,35 +1080,16 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -1081,35 +1080,16 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state)
/* Disable all Receive buffers */ /* Disable all Receive buffers */
pch_can_set_rx_all(priv, 0); pch_can_set_rx_all(priv, 0);
retval = pci_save_state(pdev);
if (retval) {
dev_err(&pdev->dev, "pci_save_state failed.\n");
} else {
pci_enable_wake(pdev, PCI_D3hot, 0);
pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
}
return retval; return 0;
} }
static int pch_can_resume(struct pci_dev *pdev) static int __maybe_unused pch_can_resume(struct device *dev_d)
{ {
int i; int i;
int retval; struct net_device *dev = dev_get_drvdata(dev_d);
struct net_device *dev = pci_get_drvdata(pdev);
struct pch_can_priv *priv = netdev_priv(dev); struct pch_can_priv *priv = netdev_priv(dev);
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
retval = pci_enable_device(pdev);
if (retval) {
dev_err(&pdev->dev, "pci_enable_device failed.\n");
return retval;
}
pci_enable_wake(pdev, PCI_D3hot, 0);
priv->can.state = CAN_STATE_ERROR_ACTIVE; priv->can.state = CAN_STATE_ERROR_ACTIVE;
/* Disabling all interrupts. */ /* Disabling all interrupts. */
...@@ -1146,12 +1126,8 @@ static int pch_can_resume(struct pci_dev *pdev) ...@@ -1146,12 +1126,8 @@ static int pch_can_resume(struct pci_dev *pdev)
/* Restore Run Mode */ /* Restore Run Mode */
pch_can_set_run_mode(priv, PCH_CAN_RUN); pch_can_set_run_mode(priv, PCH_CAN_RUN);
return retval; return 0;
} }
#else
#define pch_can_suspend NULL
#define pch_can_resume NULL
#endif
static int pch_can_get_berr_counter(const struct net_device *dev, static int pch_can_get_berr_counter(const struct net_device *dev,
struct can_berr_counter *bec) struct can_berr_counter *bec)
...@@ -1252,13 +1228,16 @@ static int pch_can_probe(struct pci_dev *pdev, ...@@ -1252,13 +1228,16 @@ static int pch_can_probe(struct pci_dev *pdev,
return rc; return rc;
} }
static SIMPLE_DEV_PM_OPS(pch_can_pm_ops,
pch_can_suspend,
pch_can_resume);
static struct pci_driver pch_can_pci_driver = { static struct pci_driver pch_can_pci_driver = {
.name = "pch_can", .name = "pch_can",
.id_table = pch_pci_tbl, .id_table = pch_pci_tbl,
.probe = pch_can_probe, .probe = pch_can_probe,
.remove = pch_can_remove, .remove = pch_can_remove,
.suspend = pch_can_suspend, .driver.pm = &pch_can_pm_ops,
.resume = pch_can_resume,
}; };
module_pci_driver(pch_can_pci_driver); module_pci_driver(pch_can_pci_driver);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment