FreeBSD Bugzilla – Attachment 205447 Details for
Bug 238037
[PATCH] Implement ig4 suspend/resume
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
ig4 suspend/resume patch
ig4_suspend.diff (text/plain), 4.64 KB, created by
Austin Shafer
on 2019-07-01 01:15:36 UTC
(
hide
)
Description:
ig4 suspend/resume patch
Filename:
MIME Type:
Creator:
Austin Shafer
Created:
2019-07-01 01:15:36 UTC
Size:
4.64 KB
patch
obsolete
>Index: sys/dev/ichiic/ig4_acpi.c >=================================================================== >--- sys/dev/ichiic/ig4_acpi.c (revision 343025) >+++ sys/dev/ichiic/ig4_acpi.c (working copy) >@@ -155,6 +155,8 @@ > DEVMETHOD(device_probe, ig4iic_acpi_probe), > DEVMETHOD(device_attach, ig4iic_acpi_attach), > DEVMETHOD(device_detach, ig4iic_acpi_detach), >+ DEVMETHOD(device_suspend, bus_generic_suspend), >+ DEVMETHOD(device_resume, bus_generic_resume), > > /* iicbus interface */ > DEVMETHOD(iicbus_transfer, ig4iic_transfer), >Index: sys/dev/ichiic/ig4_pci.c >=================================================================== >--- sys/dev/ichiic/ig4_pci.c (revision 343025) >+++ sys/dev/ichiic/ig4_pci.c (working copy) >@@ -206,11 +206,105 @@ > return (0); > } > >+/* >+ * During suspend we save registers and re-initialize them >+ * during resume. This is a list of the registers to save. >+ * >+ * IG4_REGS_CONTEXT_SIZE is the length of this array. >+ * It must be updated if this list is. >+ * >+ * The regs_context field of struct ig4iic_softc holds the >+ * values of the saved registers. >+ */ >+uint32_t regs_context_ids[IG4_REGS_CONTEXT_SIZE] = { >+ IG4_REG_CTL, >+ IG4_REG_TAR_ADD, >+ IG4_REG_DATA_CMD, >+ IG4_REG_SS_SCL_HCNT, >+ IG4_REG_SS_SCL_LCNT, >+ IG4_REG_FS_SCL_HCNT, >+ IG4_REG_FS_SCL_LCNT, >+ IG4_REG_INTR_MASK, >+ IG4_REG_RX_TL, >+ IG4_REG_TX_TL, >+ IG4_REG_I2C_EN, >+ IG4_REG_SDA_HOLD, >+ IG4_REG_SLV_DATA_NACK, >+ IG4_REG_DMA_CTRL, >+ IG4_REG_DMA_TDLR, >+ IG4_REG_DMA_RDLR, >+ IG4_REG_SDA_SETUP, >+ IG4_REG_GENERAL, >+ IG4_REG_ACK_GENERAL_CALL, >+ IG4_REG_SW_LTR_VALUE, >+ IG4_REG_AUTO_LTR_VALUE, >+}; >+ >+static int >+ig4iic_pci_suspend(device_t dev) >+{ >+ ig4iic_softc_t *sc; >+ >+ sc = device_get_softc(dev); >+ >+ /* RESETS spec (22.2.36) recommends saving and re-initializing registers */ >+ for (int i = 0; i < IG4_REGS_CONTEXT_SIZE; i++) { >+ bus_barrier(sc->regs_res, regs_context_ids[i], 4, BUS_SPACE_BARRIER_READ); >+ sc->regs_context[i] = bus_read_4(sc->regs_res, regs_context_ids[i]); >+ } >+ >+ /* >+ * reset the controller before we suspend >+ * Haswell and Skylake apparently have different RESET methods >+ */ >+ if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { >+ bus_write_4(sc->regs_res, IG4_REG_RESETS_HSW, IG4_RESETS_ASSERT_HSW); >+ bus_barrier(sc->regs_res, IG4_REG_RESETS_HSW, 4, BUS_SPACE_BARRIER_WRITE); >+ } else if (sc->version == IG4_SKYLAKE) { >+ bus_write_4(sc->regs_res, IG4_REG_RESETS_SKL, IG4_RESETS_ASSERT_SKL); >+ bus_barrier(sc->regs_res, IG4_REG_RESETS_SKL, 4, BUS_SPACE_BARRIER_WRITE); >+ } else { >+ device_printf(dev, "Unable to assert reset, reset register unavailable\n"); >+ } >+ >+ /* suspend all children */ >+ return bus_generic_suspend(dev); >+} >+ >+static int >+ig4iic_pci_resume(device_t dev) >+{ >+ ig4iic_softc_t *sc; >+ >+ sc = device_get_softc(dev); >+ >+ /* wake the controller before its children */ >+ if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { >+ bus_write_4(sc->regs_res, IG4_REG_RESETS_HSW, IG4_RESETS_DEASSERT_HSW); >+ bus_barrier(sc->regs_res, IG4_REG_RESETS_HSW, 4, BUS_SPACE_BARRIER_WRITE); >+ } else if (sc->version == IG4_SKYLAKE) { >+ bus_write_4(sc->regs_res, IG4_REG_RESETS_SKL, IG4_RESETS_DEASSERT_SKL); >+ bus_barrier(sc->regs_res, IG4_REG_RESETS_SKL, 4, BUS_SPACE_BARRIER_WRITE); >+ } else { >+ device_printf(dev, "Unable to deassert reset, reset register unavailable\n"); >+ } >+ >+ /* set registers to values previously saved in regs_context */ >+ for (int i = 0; i < IG4_REGS_CONTEXT_SIZE; i++) { >+ bus_write_4(sc->regs_res, regs_context_ids[i], sc->regs_context[i]); >+ bus_barrier(sc->regs_res, regs_context_ids[i], 4, BUS_SPACE_BARRIER_WRITE); >+ } >+ >+ return bus_generic_resume(dev); >+} >+ > static device_method_t ig4iic_pci_methods[] = { > /* Device interface */ > DEVMETHOD(device_probe, ig4iic_pci_probe), > DEVMETHOD(device_attach, ig4iic_pci_attach), > DEVMETHOD(device_detach, ig4iic_pci_detach), >+ DEVMETHOD(device_suspend, ig4iic_pci_suspend), >+ DEVMETHOD(device_resume, ig4iic_pci_resume), > > DEVMETHOD(iicbus_transfer, ig4iic_transfer), > DEVMETHOD(iicbus_reset, ig4iic_reset), >Index: sys/dev/ichiic/ig4_var.h >=================================================================== >--- sys/dev/ichiic/ig4_var.h (revision 343025) >+++ sys/dev/ichiic/ig4_var.h (working copy) >@@ -49,6 +49,9 @@ > enum ig4_op { IG4_IDLE, IG4_READ, IG4_WRITE }; > enum ig4_vers { IG4_HASWELL, IG4_ATOM, IG4_SKYLAKE, IG4_APL }; > >+/* length of the register context array (regs_context_ids) */ >+#define IG4_REGS_CONTEXT_SIZE 21 >+ > struct ig4iic_softc { > device_t dev; > struct intr_config_hook enum_hook; >@@ -55,6 +58,7 @@ > device_t iicbus; > struct resource *regs_res; > int regs_rid; >+ uint32_t regs_context[IG4_REGS_CONTEXT_SIZE]; > struct resource *intr_res; > int intr_rid; > void *intr_handle;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 238037
:
204527
|
205417
|
205432
| 205447 |
205461
|
205573
|
205867
|
207593