linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] gpio: OF: separation of concerns
@ 2016-10-03  9:02 Linus Walleij
  2016-10-03  9:02 ` [PATCH 2/3] gpio: acpi: " Linus Walleij
  2016-10-03  9:02 ` [PATCH 3/3] gpio: OF: localize some gpiochip init functions Linus Walleij
  0 siblings, 2 replies; 6+ messages in thread
From: Linus Walleij @ 2016-10-03  9:02 UTC (permalink / raw)
  To: linux-gpio, Alexandre Courbot; +Cc: Linus Walleij

The generic GPIO library directly implement code for of_find_gpio()
which is only used with CONFIG_OF and causes compilation problems
on archs that do not even have stubs for OF functions, especially
on UM that does not implement any IO remap functions.

Move the function to gpiolib-of.c, implement a static inline stub
in gpiolib.h returning PTR_ERR(-ENOENT) if CONFIG_OF_GPIO is not
set and be done with it.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpiolib-of.c | 39 +++++++++++++++++++++++++++++++++++++++
 drivers/gpio/gpiolib.c    | 39 ---------------------------------------
 drivers/gpio/gpiolib.h    | 16 ++++++++++++++++
 3 files changed, 55 insertions(+), 39 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 75e7b3919ea7..33b05c8de42f 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -114,6 +114,45 @@ int of_get_named_gpio_flags(struct device_node *np, const char *list_name,
 }
 EXPORT_SYMBOL(of_get_named_gpio_flags);
 
+struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
+			       unsigned int idx,
+			       enum gpio_lookup_flags *flags)
+{
+	char prop_name[32]; /* 32 is max size of property name */
+	enum of_gpio_flags of_flags;
+	struct gpio_desc *desc;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
+		if (con_id)
+			snprintf(prop_name, sizeof(prop_name), "%s-%s", con_id,
+				 gpio_suffixes[i]);
+		else
+			snprintf(prop_name, sizeof(prop_name), "%s",
+				 gpio_suffixes[i]);
+
+		desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx,
+						&of_flags);
+		if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT))
+			break;
+	}
+
+	if (IS_ERR(desc))
+		return desc;
+
+	if (of_flags & OF_GPIO_ACTIVE_LOW)
+		*flags |= GPIO_ACTIVE_LOW;
+
+	if (of_flags & OF_GPIO_SINGLE_ENDED) {
+		if (of_flags & OF_GPIO_ACTIVE_LOW)
+			*flags |= GPIO_OPEN_DRAIN;
+		else
+			*flags |= GPIO_OPEN_SOURCE;
+	}
+
+	return desc;
+}
+
 /**
  * of_parse_own_gpio() - Get a GPIO hog descriptor, names and flags for GPIO API
  * @np:		device node to get GPIO from
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 19a665f8d455..5404cdcfed19 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2883,45 +2883,6 @@ void gpiod_remove_lookup_table(struct gpiod_lookup_table *table)
 	mutex_unlock(&gpio_lookup_lock);
 }
 
-static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
-				      unsigned int idx,
-				      enum gpio_lookup_flags *flags)
-{
-	char prop_name[32]; /* 32 is max size of property name */
-	enum of_gpio_flags of_flags;
-	struct gpio_desc *desc;
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
-		if (con_id)
-			snprintf(prop_name, sizeof(prop_name), "%s-%s", con_id,
-				 gpio_suffixes[i]);
-		else
-			snprintf(prop_name, sizeof(prop_name), "%s",
-				 gpio_suffixes[i]);
-
-		desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx,
-						&of_flags);
-		if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT))
-			break;
-	}
-
-	if (IS_ERR(desc))
-		return desc;
-
-	if (of_flags & OF_GPIO_ACTIVE_LOW)
-		*flags |= GPIO_ACTIVE_LOW;
-
-	if (of_flags & OF_GPIO_SINGLE_ENDED) {
-		if (of_flags & OF_GPIO_ACTIVE_LOW)
-			*flags |= GPIO_OPEN_DRAIN;
-		else
-			*flags |= GPIO_OPEN_SOURCE;
-	}
-
-	return desc;
-}
-
 static struct gpio_desc *acpi_find_gpio(struct device *dev,
 					const char *con_id,
 					unsigned int idx,
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 2d9ea5e0cab3..cc7fd56d7c9b 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -13,6 +13,7 @@
 #define GPIOLIB_H
 
 #include <linux/gpio/driver.h>
+#include <linux/gpio/machine.h>
 #include <linux/err.h>
 #include <linux/device.h>
 #include <linux/module.h>
@@ -86,6 +87,21 @@ struct acpi_gpio_info {
 /* gpio suffixes used for ACPI and device tree lookup */
 static const char * const gpio_suffixes[] = { "gpios", "gpio" };
 
+#ifdef CONFIG_OF_GPIO
+struct gpio_desc *of_find_gpio(struct device *dev,
+			       const char *con_id,
+			       unsigned int idx,
+			       enum gpio_lookup_flags *flags);
+#else
+static inline struct gpio_desc *of_find_gpio(struct device *dev,
+					     const char *con_id,
+					     unsigned int idx,
+					     enum gpio_lookup_flags *flags)
+{
+	return ERR_PTR(-ENOENT);
+}
+#endif /* CONFIG_OF_GPIO */
+
 #ifdef CONFIG_ACPI
 void acpi_gpiochip_add(struct gpio_chip *chip);
 void acpi_gpiochip_remove(struct gpio_chip *chip);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/3] gpio: acpi: separation of concerns
  2016-10-03  9:02 [PATCH 1/3] gpio: OF: separation of concerns Linus Walleij
@ 2016-10-03  9:02 ` Linus Walleij
  2016-10-03 10:24   ` Mika Westerberg
  2016-10-03  9:02 ` [PATCH 3/3] gpio: OF: localize some gpiochip init functions Linus Walleij
  1 sibling, 1 reply; 6+ messages in thread
From: Linus Walleij @ 2016-10-03  9:02 UTC (permalink / raw)
  To: linux-gpio, Alexandre Courbot
  Cc: Linus Walleij, Mika Westerberg, Rafael J . Wysocki

The generic GPIO library directly implement code for acpi_find_gpio()
which is only used with CONFIG_ACPI. This was probably done because
OF did the same thing, but I removed that so remove this too.

Rename the internal acpi_find_gpio() in gpiolib-acpi.c to
acpi_populate_gpio_lookup() which seems to be more appropriate anyway
so as to avoid a namespace clash with the same function.

Make the stub return -ENOENT rather than -ENOSYS (as that is for
syscalls!).

Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpiolib-acpi.c | 56 ++++++++++++++++++++++++++++++++++++++++++---
 drivers/gpio/gpiolib.c      | 49 ---------------------------------------
 drivers/gpio/gpiolib.h      | 15 +++++++-----
 3 files changed, 62 insertions(+), 58 deletions(-)

diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index af514618d7fb..5aca4053e06a 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -395,7 +395,7 @@ struct acpi_gpio_lookup {
 	int n;
 };
 
-static int acpi_find_gpio(struct acpi_resource *ares, void *data)
+static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data)
 {
 	struct acpi_gpio_lookup *lookup = data;
 
@@ -440,7 +440,8 @@ static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup,
 
 	INIT_LIST_HEAD(&res_list);
 
-	ret = acpi_dev_get_resources(lookup->adev, &res_list, acpi_find_gpio,
+	ret = acpi_dev_get_resources(lookup->adev, &res_list,
+				     acpi_populate_gpio_lookup,
 				     lookup);
 	if (ret < 0)
 		return ret;
@@ -513,7 +514,7 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode,
  * Note: if the GPIO resource has multiple entries in the pin list, this
  * function only returns the first.
  */
-struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
+static struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
 					  const char *propname, int index,
 					  struct acpi_gpio_info *info)
 {
@@ -546,6 +547,55 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
 	return ret ? ERR_PTR(ret) : lookup.desc;
 }
 
+struct gpio_desc *acpi_find_gpio(struct device *dev,
+				 const char *con_id,
+				 unsigned int idx,
+				 enum gpiod_flags flags,
+				 enum gpio_lookup_flags *lookupflags)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	struct acpi_gpio_info info;
+	struct gpio_desc *desc;
+	char propname[32];
+	int i;
+
+	/* Try first from _DSD */
+	for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
+		if (con_id && strcmp(con_id, "gpios")) {
+			snprintf(propname, sizeof(propname), "%s-%s",
+				 con_id, gpio_suffixes[i]);
+		} else {
+			snprintf(propname, sizeof(propname), "%s",
+				 gpio_suffixes[i]);
+		}
+
+		desc = acpi_get_gpiod_by_index(adev, propname, idx, &info);
+		if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER))
+			break;
+	}
+
+	/* Then from plain _CRS GPIOs */
+	if (IS_ERR(desc)) {
+		if (!acpi_can_fallback_to_crs(adev, con_id))
+			return ERR_PTR(-ENOENT);
+
+		desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info);
+		if (IS_ERR(desc))
+			return desc;
+
+		if ((flags == GPIOD_OUT_LOW || flags == GPIOD_OUT_HIGH) &&
+		    info.gpioint) {
+			dev_dbg(dev, "refusing GpioInt() entry when doing GPIOD_OUT_* lookup\n");
+			return ERR_PTR(-ENOENT);
+		}
+	}
+
+	if (info.polarity == GPIO_ACTIVE_LOW)
+		*lookupflags |= GPIO_ACTIVE_LOW;
+
+	return desc;
+}
+
 /**
  * acpi_node_get_gpiod() - get a GPIO descriptor from ACPI resources
  * @fwnode: pointer to an ACPI firmware node to get the GPIO information from
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 5404cdcfed19..f0fc3a0d37c8 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2883,55 +2883,6 @@ void gpiod_remove_lookup_table(struct gpiod_lookup_table *table)
 	mutex_unlock(&gpio_lookup_lock);
 }
 
-static struct gpio_desc *acpi_find_gpio(struct device *dev,
-					const char *con_id,
-					unsigned int idx,
-					enum gpiod_flags flags,
-					enum gpio_lookup_flags *lookupflags)
-{
-	struct acpi_device *adev = ACPI_COMPANION(dev);
-	struct acpi_gpio_info info;
-	struct gpio_desc *desc;
-	char propname[32];
-	int i;
-
-	/* Try first from _DSD */
-	for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
-		if (con_id && strcmp(con_id, "gpios")) {
-			snprintf(propname, sizeof(propname), "%s-%s",
-				 con_id, gpio_suffixes[i]);
-		} else {
-			snprintf(propname, sizeof(propname), "%s",
-				 gpio_suffixes[i]);
-		}
-
-		desc = acpi_get_gpiod_by_index(adev, propname, idx, &info);
-		if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER))
-			break;
-	}
-
-	/* Then from plain _CRS GPIOs */
-	if (IS_ERR(desc)) {
-		if (!acpi_can_fallback_to_crs(adev, con_id))
-			return ERR_PTR(-ENOENT);
-
-		desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info);
-		if (IS_ERR(desc))
-			return desc;
-
-		if ((flags == GPIOD_OUT_LOW || flags == GPIOD_OUT_HIGH) &&
-		    info.gpioint) {
-			dev_dbg(dev, "refusing GpioInt() entry when doing GPIOD_OUT_* lookup\n");
-			return ERR_PTR(-ENOENT);
-		}
-	}
-
-	if (info.polarity == GPIO_ACTIVE_LOW)
-		*lookupflags |= GPIO_ACTIVE_LOW;
-
-	return desc;
-}
-
 static struct gpiod_lookup_table *gpiod_find_lookup_table(struct device *dev)
 {
 	const char *dev_id = dev ? dev_name(dev) : NULL;
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index cc7fd56d7c9b..9ef9cfee788d 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -109,9 +109,11 @@ void acpi_gpiochip_remove(struct gpio_chip *chip);
 void acpi_gpiochip_request_interrupts(struct gpio_chip *chip);
 void acpi_gpiochip_free_interrupts(struct gpio_chip *chip);
 
-struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
-					  const char *propname, int index,
-					  struct acpi_gpio_info *info);
+struct gpio_desc *acpi_find_gpio(struct device *dev,
+				 const char *con_id,
+				 unsigned int idx,
+				 enum gpiod_flags flags,
+				 enum gpio_lookup_flags *lookupflags);
 struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
 				      const char *propname, int index,
 				      struct acpi_gpio_info *info);
@@ -130,10 +132,11 @@ static inline void
 acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { }
 
 static inline struct gpio_desc *
-acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname,
-			int index, struct acpi_gpio_info *info)
+acpi_find_gpio(struct device *dev, const char *con_id,
+	       unsigned int idx, enum gpiod_flags flags,
+	       enum gpio_lookup_flags *lookupflags)
 {
-	return ERR_PTR(-ENOSYS);
+	return ERR_PTR(-ENOENT);
 }
 static inline struct gpio_desc *
 acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname,
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/3] gpio: OF: localize some gpiochip init functions
  2016-10-03  9:02 [PATCH 1/3] gpio: OF: separation of concerns Linus Walleij
  2016-10-03  9:02 ` [PATCH 2/3] gpio: acpi: " Linus Walleij
@ 2016-10-03  9:02 ` Linus Walleij
  1 sibling, 0 replies; 6+ messages in thread
From: Linus Walleij @ 2016-10-03  9:02 UTC (permalink / raw)
  To: linux-gpio, Alexandre Courbot; +Cc: Linus Walleij

of_gpiochip_add() and of_gpiochip_remove() are only used locally
in the gpio subsystem so move these functions to the local
header.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpiolib.h  | 4 ++++
 include/linux/of_gpio.h | 5 -----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 9ef9cfee788d..ba1e383079a3 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -92,6 +92,8 @@ struct gpio_desc *of_find_gpio(struct device *dev,
 			       const char *con_id,
 			       unsigned int idx,
 			       enum gpio_lookup_flags *flags);
+int of_gpiochip_add(struct gpio_chip *gc);
+void of_gpiochip_remove(struct gpio_chip *gc);
 #else
 static inline struct gpio_desc *of_find_gpio(struct device *dev,
 					     const char *con_id,
@@ -100,6 +102,8 @@ static inline struct gpio_desc *of_find_gpio(struct device *dev,
 {
 	return ERR_PTR(-ENOENT);
 }
+static inline int of_gpiochip_add(struct gpio_chip *gc) { return 0; }
+static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
 #endif /* CONFIG_OF_GPIO */
 
 #ifdef CONFIG_ACPI
diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
index 092186c62ff4..3f87ea5b8bee 100644
--- a/include/linux/of_gpio.h
+++ b/include/linux/of_gpio.h
@@ -61,8 +61,6 @@ static inline int of_mm_gpiochip_add(struct device_node *np,
 }
 extern void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc);
 
-extern int of_gpiochip_add(struct gpio_chip *gc);
-extern void of_gpiochip_remove(struct gpio_chip *gc);
 extern int of_gpio_simple_xlate(struct gpio_chip *gc,
 				const struct of_phandle_args *gpiospec,
 				u32 *flags);
@@ -86,9 +84,6 @@ static inline int of_gpio_simple_xlate(struct gpio_chip *gc,
 	return -ENOSYS;
 }
 
-static inline int of_gpiochip_add(struct gpio_chip *gc) { return 0; }
-static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
-
 #endif /* CONFIG_OF_GPIO */
 
 /**
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/3] gpio: acpi: separation of concerns
  2016-10-03  9:02 ` [PATCH 2/3] gpio: acpi: " Linus Walleij
@ 2016-10-03 10:24   ` Mika Westerberg
  2016-10-03 12:36     ` Linus Walleij
  0 siblings, 1 reply; 6+ messages in thread
From: Mika Westerberg @ 2016-10-03 10:24 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-gpio, Alexandre Courbot, Rafael J . Wysocki

On Mon, Oct 03, 2016 at 11:02:39AM +0200, Linus Walleij wrote:
> The generic GPIO library directly implement code for acpi_find_gpio()
> which is only used with CONFIG_ACPI. This was probably done because
> OF did the same thing, but I removed that so remove this too.

Yes, it was originally copied from the DT implementation.

> Rename the internal acpi_find_gpio() in gpiolib-acpi.c to
> acpi_populate_gpio_lookup() which seems to be more appropriate anyway
> so as to avoid a namespace clash with the same function.
> 
> Make the stub return -ENOENT rather than -ENOSYS (as that is for
> syscalls!).

-ENXIO?

> Cc: Mika Westerberg <mika.westerberg@linux.intel.com>

Regardless of that,

Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/3] gpio: acpi: separation of concerns
  2016-10-03 10:24   ` Mika Westerberg
@ 2016-10-03 12:36     ` Linus Walleij
  2016-10-03 12:44       ` Mika Westerberg
  0 siblings, 1 reply; 6+ messages in thread
From: Linus Walleij @ 2016-10-03 12:36 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-gpio@vger.kernel.org, Alexandre Courbot, Rafael J . Wysocki

On Mon, Oct 3, 2016 at 12:24 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Mon, Oct 03, 2016 at 11:02:39AM +0200, Linus Walleij wrote:
>> The generic GPIO library directly implement code for acpi_find_gpio()
>> which is only used with CONFIG_ACPI. This was probably done because
>> OF did the same thing, but I removed that so remove this too.
>
> Yes, it was originally copied from the DT implementation.
>
>> Rename the internal acpi_find_gpio() in gpiolib-acpi.c to
>> acpi_populate_gpio_lookup() which seems to be more appropriate anyway
>> so as to avoid a namespace clash with the same function.
>>
>> Make the stub return -ENOENT rather than -ENOSYS (as that is for
>> syscalls!).
>
> -ENXIO?

Sorry for not writing all that I think.

The code works like such that if -ENOENT is returned, the core
will proceed to check for presence of boardfile-type hardcoded
descriptor tables. Which might be relevant.

(The mechanism should be used as fallback also when no
desc is found in the ACPI lookup, actually.)

>> Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
>
> Regardless of that,
>
> Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>

Thanks!

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/3] gpio: acpi: separation of concerns
  2016-10-03 12:36     ` Linus Walleij
@ 2016-10-03 12:44       ` Mika Westerberg
  0 siblings, 0 replies; 6+ messages in thread
From: Mika Westerberg @ 2016-10-03 12:44 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-gpio@vger.kernel.org, Alexandre Courbot, Rafael J . Wysocki

On Mon, Oct 03, 2016 at 02:36:50PM +0200, Linus Walleij wrote:
> > -ENXIO?
> 
> Sorry for not writing all that I think.
> 
> The code works like such that if -ENOENT is returned, the core
> will proceed to check for presence of boardfile-type hardcoded
> descriptor tables. Which might be relevant.
> 
> (The mechanism should be used as fallback also when no
> desc is found in the ACPI lookup, actually.)

Makes sense. Thanks for the clarification.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-10-03 12:44 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-10-03  9:02 [PATCH 1/3] gpio: OF: separation of concerns Linus Walleij
2016-10-03  9:02 ` [PATCH 2/3] gpio: acpi: " Linus Walleij
2016-10-03 10:24   ` Mika Westerberg
2016-10-03 12:36     ` Linus Walleij
2016-10-03 12:44       ` Mika Westerberg
2016-10-03  9:02 ` [PATCH 3/3] gpio: OF: localize some gpiochip init functions Linus Walleij

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).