diff --git a/.gitignore b/.gitignore
index 45f6aa481dde..4899534e57e5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 *.o
+*.xml
 .deps/
 .libs/
 Makefile
diff --git a/Documentation/Makefile.am b/Documentation/Makefile.am
new file mode 100644
index 000000000000..bd43714d5215
--- /dev/null
+++ b/Documentation/Makefile.am
@@ -0,0 +1,26 @@
+man1_MANS = \
+	ndctl.1 \
+	ndctl-zero-labels.1 \
+	ndctl-enable-region.1 \
+	ndctl-disable-region.1 \
+	ndctl-enable-namespace.1 \
+	ndctl-disable-namespace.1
+
+XML_DEPS = \
+	$(top_srcdir)/version.m4 \
+	Makefile \
+	region-description.txt \
+	xable-region-options.txt \
+	xable-namespace-options.txt
+
+RM ?= rm -f
+
+%.xml: %.txt $(XML_DEPS)
+	$(AM_V_GEN)$(RM) $@+ $@ && \
+		$(ASCIIDOC) -b docbook -d manpage -f asciidoc.conf \
+		--unsafe -andctl_version=$(VERSION) -o $@+ $< && \
+		mv $@+ $@
+
+%.1: %.xml
+	$(AM_V_GEN)$(RM) $@ && \
+		$(XMLTO) -o . -m manpage-normal.xsl man $<
diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf
new file mode 100644
index 000000000000..26a822a17b7b
--- /dev/null
+++ b/Documentation/asciidoc.conf
@@ -0,0 +1,91 @@
+## linkndctl: macro
+#
+# Usage: linkndctl:command[manpage-section]
+#
+# Note, {0} is the manpage section, while {target} is the command.
+#
+# Show PERF link as: <command>(<section>); if section is defined, else just show
+# the command.
+
+[macros]
+(?su)[\\]?(?P<name>linkndctl):(?P<target>\S*?)\[(?P<attrlist>.*?)\]=
+
+[attributes]
+asterisk=&#42;
+plus=&#43;
+caret=&#94;
+startsb=&#91;
+endsb=&#93;
+tilde=&#126;
+
+ifdef::backend-docbook[]
+[linkndctl-inlinemacro]
+{0%{target}}
+{0#<citerefentry>}
+{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>}
+{0#</citerefentry>}
+endif::backend-docbook[]
+
+ifdef::backend-docbook[]
+ifndef::ndctl-asciidoc-no-roff[]
+# "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this.
+# v1.72 breaks with this because it replaces dots not in roff requests.
+[listingblock]
+<example><title>{title}</title>
+<literallayout>
+ifdef::doctype-manpage[]
+&#10;.ft C&#10;
+endif::doctype-manpage[]
+|
+ifdef::doctype-manpage[]
+&#10;.ft&#10;
+endif::doctype-manpage[]
+</literallayout>
+{title#}</example>
+endif::ndctl-asciidoc-no-roff[]
+
+ifdef::ndctl-asciidoc-no-roff[]
+ifdef::doctype-manpage[]
+# The following two small workarounds insert a simple paragraph after screen
+[listingblock]
+<example><title>{title}</title>
+<literallayout>
+|
+</literallayout><simpara></simpara>
+{title#}</example>
+
+[verseblock]
+<formalpara{id? id="{id}"}><title>{title}</title><para>
+{title%}<literallayout{id? id="{id}"}>
+{title#}<literallayout>
+|
+</literallayout>
+{title#}</para></formalpara>
+{title%}<simpara></simpara>
+endif::doctype-manpage[]
+endif::ndctl-asciidoc-no-roff[]
+endif::backend-docbook[]
+
+ifdef::doctype-manpage[]
+ifdef::backend-docbook[]
+[header]
+template::[header-declarations]
+<refentry>
+<refmeta>
+<refentrytitle>{mantitle}</refentrytitle>
+<manvolnum>{manvolnum}</manvolnum>
+<refmiscinfo class="source">ndctl</refmiscinfo>
+<refmiscinfo class="version">{ndctl_version}</refmiscinfo>
+<refmiscinfo class="manual">ndctl Manual</refmiscinfo>
+</refmeta>
+<refnamediv>
+  <refname>{manname}</refname>
+  <refpurpose>{manpurpose}</refpurpose>
+</refnamediv>
+endif::backend-docbook[]
+endif::doctype-manpage[]
+
+ifdef::backend-xhtml11[]
+[linkndctl-inlinemacro]
+<a href="{target}.html">{target}{0?({0})}</a>
+endif::backend-xhtml11[]
diff --git a/Documentation/manpage-base.xsl b/Documentation/manpage-base.xsl
new file mode 100644
index 000000000000..a264fa616093
--- /dev/null
+++ b/Documentation/manpage-base.xsl
@@ -0,0 +1,35 @@
+<!-- manpage-base.xsl:
+     special formatting for manpages rendered from asciidoc+docbook -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+		version="1.0">
+
+<!-- these params silence some output from xmlto -->
+<xsl:param name="man.output.quietly" select="1"/>
+<xsl:param name="refentry.meta.get.quietly" select="1"/>
+
+<!-- convert asciidoc callouts to man page format;
+     git.docbook.backslash and git.docbook.dot params
+     must be supplied by another XSL file or other means -->
+<xsl:template match="co">
+	<xsl:value-of select="concat(
+			      $git.docbook.backslash,'fB(',
+			      substring-after(@id,'-'),')',
+			      $git.docbook.backslash,'fR')"/>
+</xsl:template>
+<xsl:template match="calloutlist">
+	<xsl:value-of select="$git.docbook.dot"/>
+	<xsl:text>sp&#10;</xsl:text>
+	<xsl:apply-templates/>
+	<xsl:text>&#10;</xsl:text>
+</xsl:template>
+<xsl:template match="callout">
+	<xsl:value-of select="concat(
+			      $git.docbook.backslash,'fB',
+			      substring-after(@arearefs,'-'),
+			      '. ',$git.docbook.backslash,'fR')"/>
+	<xsl:apply-templates/>
+	<xsl:value-of select="$git.docbook.dot"/>
+	<xsl:text>br&#10;</xsl:text>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/Documentation/manpage-normal.xsl b/Documentation/manpage-normal.xsl
new file mode 100644
index 000000000000..a48f5b11f3dc
--- /dev/null
+++ b/Documentation/manpage-normal.xsl
@@ -0,0 +1,13 @@
+<!-- manpage-normal.xsl:
+     special settings for manpages rendered from asciidoc+docbook
+     handles anything we want to keep away from docbook-xsl 1.72.0 -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+		version="1.0">
+
+<xsl:import href="manpage-base.xsl"/>
+
+<!-- these are the normal values for the roff control characters -->
+<xsl:param name="git.docbook.backslash">\</xsl:param>
+<xsl:param name="git.docbook.dot"	>.</xsl:param>
+
+</xsl:stylesheet>
diff --git a/Documentation/namespace-description.txt b/Documentation/namespace-description.txt
new file mode 100644
index 000000000000..0446642bf308
--- /dev/null
+++ b/Documentation/namespace-description.txt
@@ -0,0 +1,6 @@
+DESCRIPTION
+-----------
+A REGION, after resolving DPA aliasing and LABEL specified boundaries,
+surfaces one or more "namespace" devices.  The arrival of a "namespace"
+device currently triggers either the nd_blk or nd_pmem driver to load
+and register a disk/block device.
diff --git a/Documentation/ndctl-disable-namespace.txt b/Documentation/ndctl-disable-namespace.txt
new file mode 100644
index 000000000000..067bc76f9148
--- /dev/null
+++ b/Documentation/ndctl-disable-namespace.txt
@@ -0,0 +1,21 @@
+ndctl-disable-namespace(1)
+=========================
+
+NAME
+----
+ndctl-disable-namespace - disable the given namespace(s)
+
+SYNOPSIS
+--------
+[verse]
+'ndctl disable-namespace' <namespace> [<options>]
+
+include::namespace-description.txt[]
+
+OPTIONS
+-------
+include::xable-namespace-options.txt[]
+
+SEE ALSO
+--------
+linkndctl:ndctl-disable-namespace[1]
diff --git a/Documentation/ndctl-disable-region.txt b/Documentation/ndctl-disable-region.txt
new file mode 100644
index 000000000000..812a00d096f0
--- /dev/null
+++ b/Documentation/ndctl-disable-region.txt
@@ -0,0 +1,22 @@
+ndctl-disable-region(1)
+=======================
+
+NAME
+----
+ndctl-disable-region - disable the given region(s) and all descendant namespaces
+
+SYNOPSIS
+--------
+[verse]
+'ndctl disable-region' <region> [<options>]
+
+include::region-description.txt[]
+
+OPTIONS
+-------
+<region>::
+include::xable-region-options.txt[]
+
+SEE ALSO
+--------
+linkndctl:ndctl-enable-region[1]
diff --git a/Documentation/ndctl-enable-namespace.txt b/Documentation/ndctl-enable-namespace.txt
new file mode 100644
index 000000000000..ece7b7e803e3
--- /dev/null
+++ b/Documentation/ndctl-enable-namespace.txt
@@ -0,0 +1,21 @@
+ndctl-enable-namespace(1)
+=========================
+
+NAME
+----
+ndctl-enable-namespace - enable the given namespace(s)
+
+SYNOPSIS
+--------
+[verse]
+'ndctl enable-namespace' <namespace> [<options>]
+
+include::namespace-description.txt[]
+
+OPTIONS
+-------
+include::xable-namespace-options.txt[]
+
+SEE ALSO
+--------
+linkndctl:ndctl-disable-namespace[1]
diff --git a/Documentation/ndctl-enable-region.txt b/Documentation/ndctl-enable-region.txt
new file mode 100644
index 000000000000..cd425aa286f2
--- /dev/null
+++ b/Documentation/ndctl-enable-region.txt
@@ -0,0 +1,22 @@
+ndctl-enable-region(1)
+====================
+
+NAME
+----
+ndctl-enable-region - enable the given region(s) and all descendant namespaces
+
+SYNOPSIS
+--------
+[verse]
+'ndctl enable-region' <region> [<options>]
+
+include::region-description.txt[]
+
+OPTIONS
+-------
+<region>::
+include::xable-region-options.txt[]
+
+SEE ALSO
+--------
+linkndctl:ndctl-disable-region[1]
diff --git a/Documentation/ndctl-zero-labels.txt b/Documentation/ndctl-zero-labels.txt
new file mode 100644
index 000000000000..d5865e34475f
--- /dev/null
+++ b/Documentation/ndctl-zero-labels.txt
@@ -0,0 +1,41 @@
+ndctl-zero-labels(1)
+====================
+
+NAME
+----
+ndctl-zero-labels - zero out the label area on a dimm or set of dimms
+
+SYNOPSIS
+--------
+[verse]
+'ndctl zero-labels' <nmem0> [<nmem1>..<nmemN>] [<options>]
+
+DESCRIPTION
+-----------
+The namespace label area is a small persistent partition of capacity
+available on some NVDIMM devices.  The label area is used to resolve
+aliasing between 'pmem' and 'blk' capacity by lineating namespace
+boundaries.  This command resets the device to its default state by
+deleting all labels.
+
+OPTIONS
+-------
+
+<memory device(s)>...::
+	One or more 'nmemX' device names. The keyword 'all' can be specified to
+	zero every dimm in the system, optionally filtered by bus id (see --bus=
+	option).
+
+-b::
+--bus=::
+	Limit zeroing to memory devices (dimms) that are on the given bus.
+	Where 'bus' can be a provider name or a bus id number.
+
+-v::
+	Turn on verbose debug messages in the library (if ndctl was built with
+	logging and debug enabled).
+
+SEE ALSO
+--------
+http://pmem.io/documents/NVDIMM_Namespace_Spec.pdf[NVDIMM Namespace
+Specification]
diff --git a/Documentation/ndctl.txt b/Documentation/ndctl.txt
new file mode 100644
index 000000000000..87d2fbfcbcf9
--- /dev/null
+++ b/Documentation/ndctl.txt
@@ -0,0 +1,43 @@
+ndctl(1)
+=======
+
+NAME
+----
+ndctl - Manage "libnvdimm" subsystem devices (Non-volatile Memory)
+
+SYNOPSIS
+--------
+[verse]
+'ndctl' [--version] [--help] [OPTIONS] COMMAND [ARGS]
+
+OPTIONS
+-------
+-v::
+--version::
+  Display ndctl version.
+
+-h::
+--help::
+  Run ndctl help command.
+
+DESCRIPTION
+-----------
+ndctl is utility for managing the "libnvdimm" kernel subsystem.
+The "libnvdimm" subsystem defines a kernel device model and control
+message interface for platform NVDIMM resources like those defined by
+the ACPI 6.0 NFIT (NVDIMM Firmware Interface Table).  Operations
+supported by the tool include, provisioning capacity (namespaces), as
+well as enumerating/enabling/disabling the devices (dimms, regions,
+namspaces) associated with an NVDIMM bus.
+
+SEE ALSO
+--------
+linkndctl:ndctl-zero-labels[1],
+linkndctl:ndctl-enable-region[1],
+linkndctl:ndctl-disable-region[1],
+linkndctl:ndctl-enable-namespace[1],
+linkndctl:ndctl-disable-namespace[1],
+https://www.kernel.org/doc/Documentation/nvdimm/nvdimm.txt[LIBNVDIMM
+Overview],
+http://pmem.io/documents/NVDIMM_Driver_Writers_Guide.pdf[NVDIMM Driver
+Writer's Guide]
diff --git a/Documentation/region-description.txt b/Documentation/region-description.txt
new file mode 100644
index 000000000000..bc3d12295c01
--- /dev/null
+++ b/Documentation/region-description.txt
@@ -0,0 +1,8 @@
+DESCRIPTION
+-----------
+A generic REGION device is registered for each PMEM range or
+BLK-aperture set.  LIBNVDIMM provides a built-in driver for these REGION
+devices.  This driver is responsible for reconciling the aliased DPA
+mappings across all regions, parsing the LABEL, if present, and then
+emitting NAMESPACE devices with the resolved/exclusive DPA-boundaries
+for the nd_pmem or nd_blk device driver to consume.
diff --git a/Documentation/xable-namespace-options.txt b/Documentation/xable-namespace-options.txt
new file mode 100644
index 000000000000..a5c876180c91
--- /dev/null
+++ b/Documentation/xable-namespace-options.txt
@@ -0,0 +1,8 @@
+<namespace>::
+A 'namespaceX.Y' device name. The keyword 'all' can be specified to carry out
+the operation on every namespace in the system, optionally filtered by region
+(see --region=option)
+
+-r::
+--region=::
+include::xable-region-options.txt[]
diff --git a/Documentation/xable-region-options.txt b/Documentation/xable-region-options.txt
new file mode 100644
index 000000000000..243510cc0742
--- /dev/null
+++ b/Documentation/xable-region-options.txt
@@ -0,0 +1,9 @@
+	A 'regionX' device name, or a region id number. The keyword 'all' can
+	be specified to carry out the operation on every region in the system,
+	optionally filtered by bus id (see --bus= option).
+
+-b::
+--bus=::
+	Enforce that the operation only be carried on devices that are
+	attached to the given bus. Where 'bus' can be a provider name or a bus
+	id number.
diff --git a/Makefile.am b/Makefile.am
index 1a0d294dd34d..d768de1492cd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,5 @@
 EXTRA_DIST =
+SUBDIRS = . Documentation
 CLEANFILES =
 ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
 AM_MAKEFLAGS = --no-print-directory
diff --git a/configure.ac b/configure.ac
index c1c0f684e35c..5f25b56aca9a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -32,6 +32,16 @@ AC_PREFIX_DEFAULT([/usr])
 
 AC_PROG_SED
 AC_PROG_MKDIR_P
+AC_CHECK_PROG(ASCIIDOC, [asciidoc], [$(which asciidoc)], [missing])
+if test "x$ASCIIDOC" = xmissing; then
+       AC_MSG_ERROR([asciidoc needed to build documentation])
+fi
+AC_SUBST([ASCIIDOC])
+AC_CHECK_PROG(XMLTO, [xmlto], [$(which xmlto)], [missing])
+if test "x$XMLTO" = xmissing; then
+       AC_MSG_ERROR([xmlto needed to build documentation])
+fi
+AC_SUBST([XMLTO])
 
 AC_C_TYPEOF
 AC_DEFINE([HAVE_STATEMENT_EXPR], 1, [Define to 1 if you have statement expressions.])
@@ -130,6 +140,7 @@ AC_SUBST([my_CFLAGS])
 AC_CONFIG_HEADERS(config.h)
 AC_CONFIG_FILES([
         Makefile
+        Documentation/Makefile
 ])
 
 AC_OUTPUT
diff --git a/contrib/ndctl.spec.in b/contrib/ndctl.spec.in
index 1b9595050bce..50dcc0833518 100644
--- a/contrib/ndctl.spec.in
+++ b/contrib/ndctl.spec.in
@@ -13,6 +13,8 @@ Url:            https://github.com/pmem/ndctl
 Source0:        %{name}-git%{gitcommit}.tar.xz
 
 BuildRequires:  autoconf
+BuildRequires:  asciidoc
+BuildRequires:  xmlto
 BuildRequires:  automake
 BuildRequires:  libtool
 BuildRequires:  pkgconfig
