diff --git a/gnu/local.mk b/gnu/local.mk
index aab22d32d4..ad24234ae5 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -582,6 +582,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/packages/textutils.scm			\
   %D%/packages/text-editors.scm			\
   %D%/packages/time.scm				\
+  %D%/packages/tlp.scm				\
   %D%/packages/tls.scm				\
   %D%/packages/tmux.scm				\
   %D%/packages/toolkits.scm			\
diff --git a/gnu/packages/linux.scm b/gnu/packages/linux.scm
index dc4f91d48f..6ce640ddf2 100644
--- a/gnu/packages/linux.scm
+++ b/gnu/packages/linux.scm
@@ -113,8 +113,8 @@
   #:use-module (gnu packages golang)
   #:use-module (gnu packages gperf)
   #:use-module (gnu packages gstreamer)
-  #:use-module (gnu packages gtk)
-  #:use-module (gnu packages haskell-apps)
+  ;; Don't import that module here, otherwise a cycle would result.
+  ;; #:use-module (gnu packages gtk)
   #:use-module (gnu packages haskell-xyz)
   #:use-module (gnu packages libunwind)
   #:use-module (gnu packages libusb)
@@ -6897,194 +6897,6 @@ The appropriate permissions must be set on the backlight or LED control
 interface in sysfs, which can be accomplished with the included udev rules.")
     (license license:expat)))
 
-(define-public tlp
-  (package
-    (name "tlp")
-    (version "1.5.0")
-    (source
-     (origin
-       (method git-fetch)
-       (uri (git-reference
-             (url "https://github.com/linrunner/TLP")
-             (commit version)))
-       (file-name (git-file-name name version))
-       (sha256
-        (base32 "0cssclk2brhwvn9dm7h5snm2svwy0c8cfr4z2cgkdkac2pfaaxw4"))))
-    (native-inputs
-     (list shellcheck))
-    (inputs
-     `(("bash" ,bash)
-       ("dbus" ,dbus)
-       ("ethtool" ,ethtool)
-       ("eudev" ,eudev)
-       ("grep" ,grep)
-       ("hdparm" ,hdparm)
-       ("inetutils" ,inetutils)
-       ("iw" ,iw)
-       ("kmod" ,kmod)
-       ("pciutils" ,pciutils)
-       ("perl" ,perl)
-       ("rfkill" ,rfkill)
-       ("sed" ,sed)
-       ("usbutils" ,usbutils)
-       ("util-linux" ,util-linux)
-       ("wireless-tools" ,wireless-tools)
-       ,@(if (let ((system (or (%current-target-system)
-                               (%current-system))))
-               (or (string-prefix? "i686-" system)
-                   (string-prefix? "x86_64-" system)))
-             `(("x86-energy-perf-policy" ,x86-energy-perf-policy))
-             '())))
-    (build-system gnu-build-system)
-    (arguments
-     ;; XXX: The full test suite is run with "checkall" but it requires
-     ;; "checkbashisms" and "perlcritic", not yet packaged in Guix.
-     `(#:test-target "shellcheck"
-       #:modules ((guix build gnu-build-system)
-                  (guix build utils)
-                  (srfi srfi-1))
-       #:phases
-       (modify-phases %standard-phases
-         (delete 'configure)            ; no configure script
-         (add-before 'build 'setenv
-           (lambda* (#:key outputs #:allow-other-keys)
-             (let ((out (assoc-ref outputs "out")))
-               (setenv "TLP_WITH_SYSTEMD" "0")
-               (setenv "TLP_NO_INIT" "1")
-               (setenv "TLP_NO_PMUTILS" "1")
-               (setenv "TLP_SBIN" (string-append out "/bin"))
-               (setenv "TLP_BATD" (string-append out "/share/tlp/bat.d"))
-               (setenv "TLP_BIN" (string-append out "/bin"))
-               (setenv "TLP_TLIB" (string-append out "/share/tlp"))
-               (setenv "TLP_FLIB" (string-append out "/share/tlp/func.d"))
-               (setenv "TLP_ULIB" (string-append out "/lib/udev"))
-               (setenv "TLP_CONFDEF"
-                       (string-append out "/share/tlp/defaults.conf"))
-               (setenv "TLP_CONFDIR" (string-append out "/etc/tlp.d"))
-               (setenv "TLP_CONFREN"
-                       (string-append out "/share/tlp/rename.conf"))
-               (setenv "TLP_ELOD"
-                       (string-append out "/lib/elogind/system-sleep"))
-               (setenv "TLP_SHCPL"
-                       (string-append out "/share/bash-completion/completions"))
-               (setenv "TLP_MAN" (string-append out "/share/man"))
-               (setenv "TLP_META" (string-append out "/share/metainfo")))))
-         (add-before 'install 'fix-installation
-           (lambda _
-             ;; Stop the Makefile from trying to create system directories.
-             (substitute* "Makefile"
-               (("\\[ -f \\$\\(_CONFUSR\\) \\]") "#")
-               (("install -d -m 755 \\$\\(_VAR\\)") "#"))))
-         (replace 'install
-           (lambda _ (invoke "make" "install-tlp" "install-man-tlp")))
-         (add-after 'install 'wrap
-           (lambda* (#:key inputs outputs #:allow-other-keys)
-             (let* ((bin (string-append (assoc-ref outputs "out") "/bin"))
-                    (bin-files (find-files bin ".*")))
-               (define (bin-directory input-name)
-                 (let ((p (assoc-ref inputs input-name)))
-                   (and p (string-append p "/bin"))))
-               (define (sbin-directory input-name)
-                 (string-append (assoc-ref inputs input-name) "/sbin"))
-               (for-each (lambda (program)
-                           (wrap-program program
-                             `("PATH" ":" prefix
-                               ,(append
-                                 (filter-map bin-directory
-                                             '("bash"
-                                               "coreutils"
-                                               "dbus"
-                                               "eudev"
-                                               "grep"
-                                               "inetutils"
-                                               "kmod"
-                                               "perl"
-                                               "sed"
-                                               "usbutils"
-                                               "util-linux"
-                                               "x86-energy-perf-policy"))
-                                 (filter-map sbin-directory
-                                             '("ethtool"
-                                               "hdparm"
-                                               "iw"
-                                               "pciutils"
-                                               "rfkill"
-                                               "wireless-tools"))))))
-                         bin-files)))))))
-    (home-page "https://linrunner.de/en/tlp/tlp.html")
-    (synopsis "Power management tool for Linux")
-    (description "TLP is a power management tool for Linux.  It comes with
-a default configuration already optimized for battery life.  Nevertheless,
-TLP is customizable to fulfil system requirements.  TLP settings are applied
-every time the power supply source is changed.")
-    ;; 'COPYING' is a custom version that says that one file is GPLv3+ and the
-    ;; rest is GPLv2+.
-    (license (list license:gpl2+ license:gpl3+))))
-
-(define-public tlpui
-  (package
-    (name "tlpui")
-    (version "1.5.0")
-    (source
-     (origin
-       (method git-fetch)
-       (uri (git-reference
-             (url "https://github.com/d4nj1/TLPUI")
-             (commit (string-append "tlpui-" version))))
-       (file-name (git-file-name name version))
-       (sha256
-        (base32 "0ca18hazxksx516nkh28f6rd0l1039nkn7mszqfy68c461061q1h"))))
-    (build-system python-build-system)
-    (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'patch-setup.py
-           ;; Install data_files to $out/share instead of /usr/share.
-           (lambda _
-             (substitute* "setup.py"
-               (("/usr/") ""))))
-         (add-after 'unpack 'use-tlp-input
-           ;; Hard-code tlp-stat filename to avoid propagating "tlp".
-           (lambda* (#:key inputs #:allow-other-keys)
-             (let ((tlp-stat (search-input-file inputs "/bin/tlp-stat")))
-               (with-directory-excursion "tlpui"
-                 (substitute* '("file.py" "settingshelper.py" "statui.py")
-                   (("which\\(\"tlp-stat\"\\)")
-                    (string-append "'" tlp-stat "'"))
-                   (("\"tlp-stat\"")
-                    (string-append "'" tlp-stat "'")))))))
-         (add-before 'check 'fix-home-directory
-           (lambda _
-             ;; Tests fail with "Permission denied:
-             ;; '/homeless-shelter'".
-             (setenv "HOME" "/tmp")))
-         ;; `sanity-check' phase errors out with the following
-         ;; messages: "Unable to init server: Could not connect:
-         ;; Connection refused" and "Error: cannot read user
-         ;; configuration from /etc/tlp.conf or /etc/default/tlp".
-         (delete 'sanity-check)
-         (replace 'check
-           (lambda _
-             (invoke "python" "-m" "discover")))
-         (add-after 'install 'wrap-gi-python
-           (lambda* (#:key outputs #:allow-other-keys)
-             (let ((out (assoc-ref outputs "out"))
-                   (gi-typelib-path (getenv "GI_TYPELIB_PATH")))
-               (wrap-program (string-append out "/bin/tlpui")
-                 `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path)))))))))
-    (native-inputs
-     (list `(,glib "bin") gobject-introspection python-discover))
-    (inputs
-     (list gtk+ python-pygobject tlp))
-    (home-page "https://github.com/d4nj1/TLPUI")
-    (synopsis "User interface for TLP written in Python")
-    (description
-     "The Python scripts in this project generate a GTK-UI to change
-TLP configuration files easily.  It aims to protect users from setting
-bad configuration and to deliver a basic overview of all the valid
-configuration values.")
-    (license license:gpl2+)))
-
 (define-public lshw
   (package
     (name "lshw")
diff --git a/gnu/packages/tlp.scm b/gnu/packages/tlp.scm
new file mode 100644
index 0000000000..dfe7d3616b
--- /dev/null
+++ b/gnu/packages/tlp.scm
@@ -0,0 +1,228 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2021 Brice Waegeneire <brice@waegenei.re>
+;;; Copyright © 2018-2022 Nicolas Goaziou <mail@nicolasgoaziou.fr>
+;;; Copyright © 2019 Stefan Stefanović <stefanx2ovic@gmail.com>
+;;; Copyright © 2019 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>
+;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu packages tlp)
+  #:use-module (guix packages)
+  #:use-module (guix build-system gnu)
+  #:use-module (guix build-system python)
+  #:use-module (guix git-download)
+  #:use-module (gnu packages admin) ;inetutils
+  #:use-module (gnu packages base) ;grep
+  #:use-module (gnu packages bash)
+  #:use-module (gnu packages check) ;python-discover
+  #:use-module (gnu packages glib) ;dbus
+  #:use-module (gnu packages haskell-apps) ;shellcheck
+  #:use-module (gnu packages gtk)
+  #:use-module (gnu packages linux) ;eudev
+  #:use-module (gnu packages networking) ;ethtool
+  #:use-module (gnu packages pciutils)
+  #:use-module (gnu packages perl) ;ethtool
+  #:use-module ((guix licenses) #:prefix license:))
+
+(define-public tlp
+  (package
+    (name "tlp")
+    (version "1.5.0")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/linrunner/TLP")
+             (commit version)))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32 "0cssclk2brhwvn9dm7h5snm2svwy0c8cfr4z2cgkdkac2pfaaxw4"))))
+    (native-inputs
+     (list shellcheck))
+    (inputs
+     `(("bash" ,bash)
+       ("dbus" ,dbus)
+       ("ethtool" ,ethtool)
+       ("eudev" ,eudev)
+       ("grep" ,grep)
+       ("hdparm" ,hdparm)
+       ("inetutils" ,inetutils)
+       ("iw" ,iw)
+       ("kmod" ,kmod)
+       ("pciutils" ,pciutils)
+       ("perl" ,perl)
+       ("rfkill" ,rfkill)
+       ("sed" ,sed)
+       ("usbutils" ,usbutils)
+       ("util-linux" ,util-linux)
+       ("wireless-tools" ,wireless-tools)
+       ,@(if (let ((system (or (%current-target-system)
+                               (%current-system))))
+               (or (string-prefix? "i686-" system)
+                   (string-prefix? "x86_64-" system)))
+             `(("x86-energy-perf-policy" ,x86-energy-perf-policy))
+             '())))
+    (build-system gnu-build-system)
+    (arguments
+     ;; XXX: The full test suite is run with "checkall" but it requires
+     ;; "checkbashisms" and "perlcritic", not yet packaged in Guix.
+     `(#:test-target "shellcheck"
+       #:modules ((guix build gnu-build-system)
+                  (guix build utils)
+                  (srfi srfi-1))
+       #:phases
+       (modify-phases %standard-phases
+         (delete 'configure)            ; no configure script
+         (add-before 'build 'setenv
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let ((out (assoc-ref outputs "out")))
+               (setenv "TLP_WITH_SYSTEMD" "0")
+               (setenv "TLP_NO_INIT" "1")
+               (setenv "TLP_NO_PMUTILS" "1")
+               (setenv "TLP_SBIN" (string-append out "/bin"))
+               (setenv "TLP_BATD" (string-append out "/share/tlp/bat.d"))
+               (setenv "TLP_BIN" (string-append out "/bin"))
+               (setenv "TLP_TLIB" (string-append out "/share/tlp"))
+               (setenv "TLP_FLIB" (string-append out "/share/tlp/func.d"))
+               (setenv "TLP_ULIB" (string-append out "/lib/udev"))
+               (setenv "TLP_CONFDEF"
+                       (string-append out "/share/tlp/defaults.conf"))
+               (setenv "TLP_CONFDIR" (string-append out "/etc/tlp.d"))
+               (setenv "TLP_CONFREN"
+                       (string-append out "/share/tlp/rename.conf"))
+               (setenv "TLP_ELOD"
+                       (string-append out "/lib/elogind/system-sleep"))
+               (setenv "TLP_SHCPL"
+                       (string-append out "/share/bash-completion/completions"))
+               (setenv "TLP_MAN" (string-append out "/share/man"))
+               (setenv "TLP_META" (string-append out "/share/metainfo")))))
+         (add-before 'install 'fix-installation
+           (lambda _
+             ;; Stop the Makefile from trying to create system directories.
+             (substitute* "Makefile"
+               (("\\[ -f \\$\\(_CONFUSR\\) \\]") "#")
+               (("install -d -m 755 \\$\\(_VAR\\)") "#"))))
+         (replace 'install
+           (lambda _ (invoke "make" "install-tlp" "install-man-tlp")))
+         (add-after 'install 'wrap
+           (lambda* (#:key inputs outputs #:allow-other-keys)
+             (let* ((bin (string-append (assoc-ref outputs "out") "/bin"))
+                    (bin-files (find-files bin ".*")))
+               (define (bin-directory input-name)
+                 (let ((p (assoc-ref inputs input-name)))
+                   (and p (string-append p "/bin"))))
+               (define (sbin-directory input-name)
+                 (string-append (assoc-ref inputs input-name) "/sbin"))
+               (for-each (lambda (program)
+                           (wrap-program program
+                             `("PATH" ":" prefix
+                               ,(append
+                                 (filter-map bin-directory
+                                             '("bash"
+                                               "coreutils"
+                                               "dbus"
+                                               "eudev"
+                                               "grep"
+                                               "inetutils"
+                                               "kmod"
+                                               "perl"
+                                               "sed"
+                                               "usbutils"
+                                               "util-linux"
+                                               "x86-energy-perf-policy"))
+                                 (filter-map sbin-directory
+                                             '("ethtool"
+                                               "hdparm"
+                                               "iw"
+                                               "pciutils"
+                                               "rfkill"
+                                               "wireless-tools"))))))
+                         bin-files)))))))
+    (home-page "https://linrunner.de/en/tlp/tlp.html")
+    (synopsis "Power management tool for Linux")
+    (description "TLP is a power management tool for Linux.  It comes with
+a default configuration already optimized for battery life.  Nevertheless,
+TLP is customizable to fulfil system requirements.  TLP settings are applied
+every time the power supply source is changed.")
+    ;; 'COPYING' is a custom version that says that one file is GPLv3+ and the
+    ;; rest is GPLv2+.
+    (license (list license:gpl2+ license:gpl3+))))
+
+(define-public tlpui
+  (package
+    (name "tlpui")
+    (version "1.5.0")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/d4nj1/TLPUI")
+             (commit (string-append "tlpui-" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32 "0ca18hazxksx516nkh28f6rd0l1039nkn7mszqfy68c461061q1h"))))
+    (build-system python-build-system)
+    (arguments
+     `(#:phases
+       (modify-phases %standard-phases
+         (add-after 'unpack 'patch-setup.py
+           ;; Install data_files to $out/share instead of /usr/share.
+           (lambda _
+             (substitute* "setup.py"
+               (("/usr/") ""))))
+         (add-after 'unpack 'use-tlp-input
+           ;; Hard-code tlp-stat filename to avoid propagating "tlp".
+           (lambda* (#:key inputs #:allow-other-keys)
+             (let ((tlp-stat (search-input-file inputs "/bin/tlp-stat")))
+               (with-directory-excursion "tlpui"
+                 (substitute* '("file.py" "settingshelper.py" "statui.py")
+                   (("which\\(\"tlp-stat\"\\)")
+                    (string-append "'" tlp-stat "'"))
+                   (("\"tlp-stat\"")
+                    (string-append "'" tlp-stat "'")))))))
+         (add-before 'check 'fix-home-directory
+           (lambda _
+             ;; Tests fail with "Permission denied:
+             ;; '/homeless-shelter'".
+             (setenv "HOME" "/tmp")))
+         ;; `sanity-check' phase errors out with the following
+         ;; messages: "Unable to init server: Could not connect:
+         ;; Connection refused" and "Error: cannot read user
+         ;; configuration from /etc/tlp.conf or /etc/default/tlp".
+         (delete 'sanity-check)
+         (replace 'check
+           (lambda _
+             (invoke "python" "-m" "discover")))
+         (add-after 'install 'wrap-gi-python
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let ((out (assoc-ref outputs "out"))
+                   (gi-typelib-path (getenv "GI_TYPELIB_PATH")))
+               (wrap-program (string-append out "/bin/tlpui")
+                 `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path)))))))))
+    (native-inputs
+     (list `(,glib "bin") gobject-introspection python-discover))
+    (inputs
+     (list gtk+ python-pygobject tlp))
+    (home-page "https://github.com/d4nj1/TLPUI")
+    (synopsis "User interface for TLP written in Python")
+    (description
+     "The Python scripts in this project generate a GTK-UI to change
+TLP configuration files easily.  It aims to protect users from setting
+bad configuration and to deliver a basic overview of all the valid
+configuration values.")
+    (license license:gpl2+)))
