diff options
Diffstat (limited to 'drivers/spi/spi-fsl-espi.c')
-rw-r--r-- | drivers/spi/spi-fsl-espi.c | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index 80d8f40f7e05..428dc7a6b62e 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c | |||
@@ -705,7 +705,7 @@ static int of_fsl_espi_probe(struct platform_device *ofdev) | |||
705 | goto err; | 705 | goto err; |
706 | 706 | ||
707 | irq = irq_of_parse_and_map(np, 0); | 707 | irq = irq_of_parse_and_map(np, 0); |
708 | if (!ret) { | 708 | if (!irq) { |
709 | ret = -EINVAL; | 709 | ret = -EINVAL; |
710 | goto err; | 710 | goto err; |
711 | } | 711 | } |
@@ -727,6 +727,66 @@ static int of_fsl_espi_remove(struct platform_device *dev) | |||
727 | return mpc8xxx_spi_remove(&dev->dev); | 727 | return mpc8xxx_spi_remove(&dev->dev); |
728 | } | 728 | } |
729 | 729 | ||
730 | #ifdef CONFIG_PM_SLEEP | ||
731 | static int of_fsl_espi_suspend(struct device *dev) | ||
732 | { | ||
733 | struct spi_master *master = dev_get_drvdata(dev); | ||
734 | struct mpc8xxx_spi *mpc8xxx_spi; | ||
735 | struct fsl_espi_reg *reg_base; | ||
736 | u32 regval; | ||
737 | int ret; | ||
738 | |||
739 | mpc8xxx_spi = spi_master_get_devdata(master); | ||
740 | reg_base = mpc8xxx_spi->reg_base; | ||
741 | |||
742 | ret = spi_master_suspend(master); | ||
743 | if (ret) { | ||
744 | dev_warn(dev, "cannot suspend master\n"); | ||
745 | return ret; | ||
746 | } | ||
747 | |||
748 | regval = mpc8xxx_spi_read_reg(®_base->mode); | ||
749 | regval &= ~SPMODE_ENABLE; | ||
750 | mpc8xxx_spi_write_reg(®_base->mode, regval); | ||
751 | |||
752 | return 0; | ||
753 | } | ||
754 | |||
755 | static int of_fsl_espi_resume(struct device *dev) | ||
756 | { | ||
757 | struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); | ||
758 | struct spi_master *master = dev_get_drvdata(dev); | ||
759 | struct mpc8xxx_spi *mpc8xxx_spi; | ||
760 | struct fsl_espi_reg *reg_base; | ||
761 | u32 regval; | ||
762 | int i; | ||
763 | |||
764 | mpc8xxx_spi = spi_master_get_devdata(master); | ||
765 | reg_base = mpc8xxx_spi->reg_base; | ||
766 | |||
767 | /* SPI controller initializations */ | ||
768 | mpc8xxx_spi_write_reg(®_base->mode, 0); | ||
769 | mpc8xxx_spi_write_reg(®_base->mask, 0); | ||
770 | mpc8xxx_spi_write_reg(®_base->command, 0); | ||
771 | mpc8xxx_spi_write_reg(®_base->event, 0xffffffff); | ||
772 | |||
773 | /* Init eSPI CS mode register */ | ||
774 | for (i = 0; i < pdata->max_chipselect; i++) | ||
775 | mpc8xxx_spi_write_reg(®_base->csmode[i], CSMODE_INIT_VAL); | ||
776 | |||
777 | /* Enable SPI interface */ | ||
778 | regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; | ||
779 | |||
780 | mpc8xxx_spi_write_reg(®_base->mode, regval); | ||
781 | |||
782 | return spi_master_resume(master); | ||
783 | } | ||
784 | #endif /* CONFIG_PM_SLEEP */ | ||
785 | |||
786 | static const struct dev_pm_ops espi_pm = { | ||
787 | SET_SYSTEM_SLEEP_PM_OPS(of_fsl_espi_suspend, of_fsl_espi_resume) | ||
788 | }; | ||
789 | |||
730 | static const struct of_device_id of_fsl_espi_match[] = { | 790 | static const struct of_device_id of_fsl_espi_match[] = { |
731 | { .compatible = "fsl,mpc8536-espi" }, | 791 | { .compatible = "fsl,mpc8536-espi" }, |
732 | {} | 792 | {} |
@@ -738,6 +798,7 @@ static struct platform_driver fsl_espi_driver = { | |||
738 | .name = "fsl_espi", | 798 | .name = "fsl_espi", |
739 | .owner = THIS_MODULE, | 799 | .owner = THIS_MODULE, |
740 | .of_match_table = of_fsl_espi_match, | 800 | .of_match_table = of_fsl_espi_match, |
801 | .pm = &espi_pm, | ||
741 | }, | 802 | }, |
742 | .probe = of_fsl_espi_probe, | 803 | .probe = of_fsl_espi_probe, |
743 | .remove = of_fsl_espi_remove, | 804 | .remove = of_fsl_espi_remove, |