LKML Archive on lore.kernel.org
 help / Atom feed
From: Bartosz Golaszewski <brgl@bgdev.pl>
To: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Cc: Boris Brezillon <boris.brezillon@bootlin.com>,
	Andrew Lunn <andrew@lunn.ch>,
	linux-doc <linux-doc@vger.kernel.org>,
	Sekhar Nori <nsekhar@ti.com>,
	Bartosz Golaszewski <bgolaszewski@baylibre.com>,
	linux-i2c <linux-i2c@vger.kernel.org>,
	Mauro Carvalho Chehab <mchehab+samsung@kernel.org>,
	Rob Herring <robh@kernel.org>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Kevin Hilman <khilman@kernel.org>,
	Richard Weinberger <richard@nod.at>,
	Russell King <linux@armlinux.org.uk>,
	Marek Vasut <marek.vasut@gmail.com>,
	Paolo Abeni <pabeni@redhat.com>,
	Dan Carpenter <dan.carpenter@oracle.com>,
	Grygorii Strashko <grygorii.strashko@ti.com>,
	David Lechner <david@lechnology.com>,
	Arnd Bergmann <arnd@arndb.de>,
	Sven Van Asbroeck <svendev@arcx.com>,
	"open list:MEMORY TECHNOLOGY..." <linux-mtd@lists.infradead.org>,
	Linux-OMAP <linux-omap@vger.kernel.org>,
	Linux ARM <linux-arm-kernel@lists.infradead.org>,
	Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jonathan Corbet <corbet@lwn.net>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Lukas Wunner <lukas@wunner.de>, Naren <naren.kernel@gmail.com>,
	netdev <netdev@vger.kernel.org>, Alban Bedel <albeu@free.fr>,
	Andrew Morton <akpm@linux-foundation.org>,
	Brian Norris <computersforpeace@gmail.com>,
	David Woodhouse <dwmw2@infradead.org>,
	"David S . Miller" <davem@davemloft.net>
Subject: Re: [PATCH v2 01/29] nvmem: add support for cell lookups
Date: Tue, 28 Aug 2018 16:41:04 +0200
Message-ID: <CAMRc=MeALxpyBQhWxGPt9BubO_ZwKGih1d8zhRzFYZ0+3kHFAA@mail.gmail.com> (raw)
In-Reply-To: <916e3e89-82b3-0d52-2b77-4374261a9d0f@linaro.org>

2018-08-28 15:45 GMT+02:00 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>:
>
>
> On 28/08/18 12:56, Bartosz Golaszewski wrote:
>>
>> 2018-08-28 12:15 GMT+02:00 Srinivas Kandagatla
>> <srinivas.kandagatla@linaro.org>:
>>>
>>>
>>> On 27/08/18 14:37, Bartosz Golaszewski wrote:
>>>>
>>>>
>>>> I didn't notice it before but there's a global list of nvmem cells
>>>
>>>
>>>
>>> Bit of history here.
>>>
>>> The global list of nvmem_cell is to assist non device tree based cell
>>> lookups. These cell entries come as part of the non-dt providers
>>> nvmem_config.
>>>
>>> All the device tree based cell lookup happen dynamically on
>>> request/demand,
>>> and all the cell definition comes from DT.
>>>
>>
>> Makes perfect sense.
>>
>>> As of today NVMEM supports both DT and non DT usecase, this is much
>>> simpler.
>>>
>>> Non dt cases have various consumer usecases.
>>>
>>> 1> Consumer is aware of provider name and cell details.
>>>          This is probably simple usecase where it can just use device
>>> based
>>> apis.
>>>
>>> 2> Consumer is not aware of provider name, its just aware of cell name.
>>>          This is the case where global list of cells are used.
>>>
>>
>> I would like to support an additional use case here: the provider is
>> generic and is not aware of its cells at all. Since the only way of
>> defining nvmem cells is through DT or nvmem_config, we lack a way to
>> allow machine code to define cells without the provider code being
>> aware.
>
>
> machine driver should be able to do
> nvmem_device_get()
> nvmem_add_cells()
>

Indeed, I missed the fact that you can retrieve the nvmem device by
name. Except that we cannot know that the nvmem provider has been
registered yet when calling nvmem_device_get(). This could potentially
be solved by my other patch that adds notifiers to nvmem, but it would
require much more boilerplate code in every board file. I think that
removing nvmem_cell_info from nvmem_config and having external cell
definitions would be cleaner.

> currently this adds to the global cell list which is exactly like doing it
> via nvmem_config.
>>
>>
>>>> with each cell referencing its owner nvmem device. I'm wondering if
>>>> this isn't some kind of inversion of ownership. Shouldn't each nvmem
>>>> device have a separate list of nvmem cells owned by it? What happens
>>>
>>>
>>> This is mainly done for use case where consumer does not have idea of
>>> provider name or any details.
>>>
>>
>> It doesn't need to know the provider details, but in most subsystems
>> the core code associates such resources by dev_id and optional con_id
>> as Boris already said.
>>
>
> If dev_id here is referring to provider dev_id, then we already do that
> using nvmem device apis, except in global cell list which makes dev_id
> optional.
>
>
>>> First thing non dt user should do is use "NVMEM device based consumer
>>> APIs"
>>>
>>> ex: First get handle to nvmem device using its nvmem provider name by
>>> calling nvmem_device_get(); and use nvmem_device_cell_read/write() apis.
>>>
>>> Also am not 100% sure how would maintaining cells list per nvmem provider
>>> would help for the intended purpose of global list?
>>>
>>
>> It would fix the use case where the consumer wants to use
>> nvmem_cell_get(dev, name) and two nvmem providers would have a cell
>> with the same name.
>
>
> There is no code to enforce duplicate checks, so this would just decrease
> the chances rather than fixing the problem totally.
> I guess this is same problem
>
> Finding cell by name without dev_id would still be an issue, am not too
> concerned about this ATM.
>
> However, the idea of having cells per provider does sound good to me.
> We should also maintain list of providers in core as a lookup in cases where
> dev_id is null.
>
> I did hack up a patch, incase you might want to try:
> I did only compile test.
> ---------------------------------->cut<-------------------------------
> Author: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> Date:   Tue Aug 28 13:46:21 2018 +0100
>
>     nvmem: core: maintain per provider cell list
>
>     Having a global cell list could be a issue in cases where the cell-id is
> same across multiple providers. Making the cell list specific to provider
> could avoid such issue by adding additional checks while addding cells.
>
>     Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>
> diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
> index aa1657831b70..29da603f2fa4 100644
> --- a/drivers/nvmem/core.c
> +++ b/drivers/nvmem/core.c
> @@ -40,6 +40,8 @@ struct nvmem_device {
>         struct device           *base_dev;
>         nvmem_reg_read_t        reg_read;
>         nvmem_reg_write_t       reg_write;
> +       struct list_head        node;
> +       struct list_head        cells;
>         void *priv;
>  };
>
> @@ -57,9 +59,7 @@ struct nvmem_cell {
>
>  static DEFINE_MUTEX(nvmem_mutex);
>  static DEFINE_IDA(nvmem_ida);
> -
> -static LIST_HEAD(nvmem_cells);
> -static DEFINE_MUTEX(nvmem_cells_mutex);
> +static LIST_HEAD(nvmem_devices);
>
>  #ifdef CONFIG_DEBUG_LOCK_ALLOC
>  static struct lock_class_key eeprom_lock_key;
> @@ -284,26 +284,28 @@ static struct nvmem_device *of_nvmem_find(struct
> device_node *nvmem_np)
>
>  static struct nvmem_cell *nvmem_find_cell(const char *cell_id)
>  {
> -       struct nvmem_cell *p;
> +       struct nvmem_device *d;
>
> -       mutex_lock(&nvmem_cells_mutex);
> -
> -       list_for_each_entry(p, &nvmem_cells, node)
> -               if (!strcmp(p->name, cell_id)) {
> -                       mutex_unlock(&nvmem_cells_mutex);
> -                       return p;
> -               }
> +       mutex_lock(&nvmem_mutex);
> +       list_for_each_entry(d, &nvmem_devices, node) {
> +               struct nvmem_cell *p;
> +               list_for_each_entry(p, &d->cells, node)
> +                       if (!strcmp(p->name, cell_id)) {
> +                               mutex_unlock(&nvmem_mutex);
> +                               return p;
> +                       }
> +       }
>
> -       mutex_unlock(&nvmem_cells_mutex);
> +       mutex_unlock(&nvmem_mutex);
>
>         return NULL;
>  }
>
>  static void nvmem_cell_drop(struct nvmem_cell *cell)
>  {
> -       mutex_lock(&nvmem_cells_mutex);
> +       mutex_lock(&nvmem_mutex);
>         list_del(&cell->node);
> -       mutex_unlock(&nvmem_cells_mutex);
> +       mutex_unlock(&nvmem_mutex);
>         kfree(cell);
>  }
>
> @@ -312,18 +314,18 @@ static void nvmem_device_remove_all_cells(const struct
> nvmem_device *nvmem)
>         struct nvmem_cell *cell;
>         struct list_head *p, *n;
>
> -       list_for_each_safe(p, n, &nvmem_cells) {
> +       list_for_each_safe(p, n, &nvmem->cells) {
>                 cell = list_entry(p, struct nvmem_cell, node);
>                 if (cell->nvmem == nvmem)
>                         nvmem_cell_drop(cell);
>         }
>  }
>
> -static void nvmem_cell_add(struct nvmem_cell *cell)
> +static void nvmem_cell_add(struct nvmem_device *nvmem, struct nvmem_cell
> *cell)
>  {
> -       mutex_lock(&nvmem_cells_mutex);
> -       list_add_tail(&cell->node, &nvmem_cells);
> -       mutex_unlock(&nvmem_cells_mutex);
> +       mutex_lock(&nvmem_mutex);
> +       list_add_tail(&cell->node, &nvmem->cells);
> +       mutex_unlock(&nvmem_mutex);
>  }
>
>  static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem,
> @@ -385,7 +387,7 @@ int nvmem_add_cells(struct nvmem_device *nvmem,
>                         goto err;
>                 }
>
> -               nvmem_cell_add(cells[i]);
> +               nvmem_cell_add(nvmem, cells[i]);
>         }
>
>         /* remove tmp array */
> @@ -519,6 +521,10 @@ struct nvmem_device *nvmem_register(const struct
> nvmem_config *config)
>         if (config->cells)
>                 nvmem_add_cells(nvmem, config->cells, config->ncells);
>
> +       mutex_lock(&nvmem_mutex);
> +       list_add_tail(&nvmem->node, &nvmem_devices);
> +       mutex_unlock(&nvmem_mutex);
> +
>         return nvmem;
>
>  err_device_del:
> @@ -544,6 +550,8 @@ int nvmem_unregister(struct nvmem_device *nvmem)
>                 mutex_unlock(&nvmem_mutex);
>                 return -EBUSY;
>         }
> +
> +       list_del(&nvmem->node);
>         mutex_unlock(&nvmem_mutex);
>
>         if (nvmem->flags & FLAG_COMPAT)
> @@ -899,7 +907,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node
> *np,
>                 goto err_sanity;
>         }
>
> -       nvmem_cell_add(cell);
> +       nvmem_cell_add(nvmem, cell);
>
>         return cell;
>
> ---------------------------------->cut<-------------------------------
>
>>
>> Next we could add a way to associate dev_ids with nvmem cells.
>>
>>>> if we have two nvmem providers with the same names for cells? I'm
>>>
>>>
>>> Yes, it would return the first instance.. which is a known issue.
>>> Am not really sure this is a big problem as of today! but am open for any
>>> better suggestions!
>>>
>>
>> Yes, I would like to rework nvmem a bit. I don't see any non-DT users
>> defining nvmem-cells using nvmem_config. I think that what we need is
>> a way of specifying cell config outside of nvmem providers in some
>> kind of structures. These tables would reference the provider by name
>> and define the cells. Then we would have an additional lookup
>> structure which would associate the consumer (by dev_id and con_id,
>> where dev_id could optionally be NULL and where we would fall back to
>> using con_id only) and the nvmem provider + cell together. Similarly
>> to how GPIO consumers are associated with the gpiochip and hwnum. How
>> does it sound?
>
> Yes, sounds good.
>
> Correct me if am wrong!
> You should be able to add the new cells using struct nvmem_cell_info and add
> them to particular provider using nvmem_add_cells().
>
> Sounds like thats exactly what nvmem_add_lookup_table() would look like.
>
> We should add new nvmem_device_cell_get(nvmem, conn_id) which would return
> nvmem cell which is specific to the provider. This cell can be used by the
> machine driver to read/write.

Except that we could do it lazily - when the nvmem provider actually
gets registered instead of doing it right away and risking that the
device isn't even there yet.

>
>>>>
>>>> BTW: of_nvmem_cell_get() seems to always allocate an nvmem_cell
>>>> instance even if the cell for this node was already added to the nvmem
>>>> device.
>>>
>>>
>>> I hope you got the reason why of_nvmem_cell_get() always allocates new
>>> instance for every get!!
>>
>>
>>
>> I admit I didn't test it, but just from reading the code it seems like
>> in nvmem_cell_get() for DT-users we'll always get to
>> of_nvmem_cell_get() and in there we always end up calling line 873:
>> cell = kzalloc(sizeof(*cell), GFP_KERNEL);
>>
> That is correct, this cell is created when we do a get and release when we
> do a put().
>

Shouldn't we add the cell to the list, and check first if it's there
and only create it if not?

Bart

  reply index

Thread overview: 92+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-10  8:04 [PATCH v2 00/29] at24: remove at24_platform_data Bartosz Golaszewski
2018-08-10  8:04 ` [PATCH v2 01/29] nvmem: add support for cell lookups Bartosz Golaszewski
2018-08-24 15:08   ` Boris Brezillon
2018-08-24 15:27     ` Andrew Lunn
2018-08-25  6:27       ` Boris Brezillon
2018-08-27  8:56         ` Bartosz Golaszewski
2018-08-27  9:00           ` Boris Brezillon
2018-08-27 13:37             ` Bartosz Golaszewski
2018-08-27 14:01               ` Boris Brezillon
2018-08-28 10:15               ` Srinivas Kandagatla
2018-08-28 11:56                 ` Bartosz Golaszewski
2018-08-28 13:45                   ` Srinivas Kandagatla
2018-08-28 14:41                     ` Bartosz Golaszewski [this message]
2018-08-28 14:48                       ` Srinivas Kandagatla
2018-08-28 14:53                       ` Boris Brezillon
2018-08-28 15:09                         ` Srinivas Kandagatla
2018-08-10  8:04 ` [PATCH v2 02/29] Documentation: nvmem: document lookup entries Bartosz Golaszewski
2018-08-31 20:30   ` Brian Norris
2018-09-01 13:11     ` Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 03/29] nvmem: add a notifier chain Bartosz Golaszewski
2018-08-10  8:33   ` Srinivas Kandagatla
2018-08-10  8:05 ` [PATCH v2 04/29] nvmem: provide nvmem_dev_name() Bartosz Golaszewski
2018-08-10  8:10   ` Srinivas Kandagatla
2018-08-10  8:05 ` [PATCH v2 05/29] nvmem: remove the name field from struct nvmem_device Bartosz Golaszewski
2018-08-10  8:33   ` Srinivas Kandagatla
2018-08-10  8:05 ` [PATCH v2 06/29] mtd: Add support for reading MTD devices via the nvmem API Bartosz Golaszewski
2018-08-17 16:27   ` Boris Brezillon
2018-08-19 11:31     ` Alban
2018-08-19 16:46       ` Boris Brezillon
2018-08-20 10:43         ` Srinivas Kandagatla
2018-08-20 18:20           ` Boris Brezillon
2018-08-20 18:50             ` Bartosz Golaszewski
2018-08-20 19:06               ` Boris Brezillon
2018-08-20 21:27             ` Alban
2018-08-21  5:07               ` Boris Brezillon
2018-08-21  9:50             ` Srinivas Kandagatla
2018-08-21  9:56               ` Boris Brezillon
2018-08-21 10:11                 ` Srinivas Kandagatla
2018-08-21 10:43                   ` Boris Brezillon
2018-08-21 11:39               ` Alban
2018-08-21 12:00                 ` Srinivas Kandagatla
2018-08-21 13:01                   ` Boris Brezillon
2018-08-23 10:29                     ` Alban
2018-08-24 14:39                       ` Boris Brezillon
2018-08-28 10:20                       ` Srinivas Kandagatla
2018-08-20 22:53         ` Alban
2018-08-21  5:44           ` Boris Brezillon
2018-08-21  9:38             ` Srinivas Kandagatla
2018-08-21 11:31               ` Boris Brezillon
2018-08-21 13:34                 ` Srinivas Kandagatla
2018-08-21 13:37                   ` Srinivas Kandagatla
2018-08-21 13:57                     ` Boris Brezillon
2018-08-21 12:27             ` Alban
2018-08-21 12:57               ` Boris Brezillon
2018-08-21 13:57                 ` Alban
2018-08-21 14:26                   ` Boris Brezillon
2018-08-21 14:33                     ` Srinivas Kandagatla
2018-08-10  8:05 ` [PATCH v2 07/29] ARM: davinci: dm365-evm: use nvmem lookup for mac address Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 08/29] ARM: davinci: dm644-evm: " Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 09/29] ARM: davinci: dm646x-evm: " Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 10/29] ARM: davinci: da830-evm: " Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 11/29] ARM: davinci: mityomapl138: add nvmem cells lookup entries Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 12/29] ARM: davinci: da850-evm: use nvmem lookup for mac address Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 13/29] ARM: davinci: da850-evm: remove unnecessary include Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 14/29] net: simplify eth_platform_get_mac_address() Bartosz Golaszewski
2018-08-10 14:39   ` Andy Shevchenko
2018-08-10 16:17     ` Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 15/29] net: split eth_platform_get_mac_address() into subroutines Bartosz Golaszewski
2018-08-31 19:54   ` Brian Norris
2018-08-10  8:05 ` [PATCH v2 16/29] net: add support for nvmem to eth_platform_get_mac_address() Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 17/29] net: davinci_emac: use eth_platform_get_mac_address() Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 18/29] ARM: davinci: da850-evm: remove dead MTD code Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 19/29] ARM: davinci: mityomapl138: don't read the MAC address from machine code Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 20/29] ARM: davinci: dm365-evm: use device properties for at24 eeprom Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 21/29] ARM: davinci: da830-evm: " Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 22/29] ARM: davinci: dm644x-evm: " Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 23/29] ARM: davinci: dm646x-evm: " Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 24/29] ARM: davinci: sffsdr: fix the at24 eeprom device name Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 25/29] ARM: davinci: sffsdr: use device properties for at24 eeprom Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 26/29] ARM: davinci: remove dead code related to MAC address reading Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 27/29] ARM: davinci: mityomapl138: use nvmem notifiers Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 28/29] ARM: davinci: mityomapl138: use device properties for at24 eeprom Bartosz Golaszewski
2018-08-10  8:05 ` [PATCH v2 29/29] eeprom: at24: kill at24_platform_data Bartosz Golaszewski
2018-08-10  8:41 ` [PATCH v2 00/29] at24: remove at24_platform_data Srinivas Kandagatla
2018-08-31 19:46 ` Brian Norris
2018-10-03 20:15   ` Bartosz Golaszewski
2018-10-03 20:30     ` Lukas Wunner
2018-10-03 21:04     ` Florian Fainelli
2018-10-04 11:06       ` Bartosz Golaszewski
2018-10-04 13:58         ` Arnd Bergmann
2018-10-04 14:35           ` Sowmini Varadhan
2018-10-04 14:38             ` Arnd Bergmann

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAMRc=MeALxpyBQhWxGPt9BubO_ZwKGih1d8zhRzFYZ0+3kHFAA@mail.gmail.com' \
    --to=brgl@bgdev.pl \
    --cc=akpm@linux-foundation.org \
    --cc=albeu@free.fr \
    --cc=andrew@lunn.ch \
    --cc=arnd@arndb.de \
    --cc=bgolaszewski@baylibre.com \
    --cc=boris.brezillon@bootlin.com \
    --cc=computersforpeace@gmail.com \
    --cc=corbet@lwn.net \
    --cc=dan.carpenter@oracle.com \
    --cc=davem@davemloft.net \
    --cc=david@lechnology.com \
    --cc=dwmw2@infradead.org \
    --cc=f.fainelli@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=grygorii.strashko@ti.com \
    --cc=ivan.khoronzhuk@linaro.org \
    --cc=khilman@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=lukas@wunner.de \
    --cc=marek.vasut@gmail.com \
    --cc=mchehab+samsung@kernel.org \
    --cc=naren.kernel@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=nsekhar@ti.com \
    --cc=pabeni@redhat.com \
    --cc=richard@nod.at \
    --cc=robh@kernel.org \
    --cc=srinivas.kandagatla@linaro.org \
    --cc=svendev@arcx.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

LKML Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git
	git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git
	git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git
	git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git
	git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git
	git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git
	git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git
	git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \
		linux-kernel@vger.kernel.org linux-kernel@archiver.kernel.org
	public-inbox-index lkml


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel


AGPL code for this site: git clone https://public-inbox.org/ public-inbox