Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] net: ethernet: cpsw-phy-sel: prefer phandle for phy sel and update binding
From: Tony Lindgren @ 2018-08-08 13:48 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: David Miller, netdev, linux-omap, devicetree, Grygorii Strashko,
	Ivan Khoronzhuk, Mark Rutland, Murali Karicheri, Rob Herring
In-Reply-To: <20180808115838.GA18314@lunn.ch>

* Andrew Lunn <andrew@lunn.ch> [180808 12:02]:
> > +++ b/Documentation/devicetree/bindings/net/cpsw.txt
> > @@ -19,6 +19,9 @@ Required properties:
> >  - slaves		: Specifies number for slaves
> >  - active_slave		: Specifies the slave to use for time stamping,
> >  			  ethtool and SIOCGMIIPHY
> > +- cpsw-phy-sel		: Specifies the phandle to the CPSW phy mode selection
> > +			  device. Note that in legacy cases cpsw-phy-sel may be
> > +			  a child device instead of a phandle.
> 
> Hi Tony
> 
> It would be good to reference cpsw-phy-sel.txt.

OK will add.

> > --- a/drivers/net/ethernet/ti/cpsw-phy-sel.c
> > +++ b/drivers/net/ethernet/ti/cpsw-phy-sel.c
> > @@ -170,10 +170,13 @@ void cpsw_phy_sel(struct device *dev, phy_interface_t phy_mode, int slave)
> >  	struct device_node *node;
> >  	struct cpsw_phy_sel_priv *priv;
> >  
> > -	node = of_get_child_by_name(dev->of_node, "cpsw-phy-sel");
> > +	node = of_parse_phandle(dev->of_node, "cpsw-phy-sel", 0);
> >  	if (!node) {
> 
> Do you need to handle EPROBE_DEFER here? The phandle points to a
> device which has not yet been loaded? I'm not sure exactly where it
> will be returned, maybe it is bus_find_device(), but i expect to see
> some handling of it somewhere in this function.

With the proper interconnect hierarchy in the device tree there should be
no EPROBE_DEFER happening here as the interconnects are probed in the
right order with the always on interrupt with system control module first :)

But then again, adding support for EPROBE_DEFER here won't hurt either,
will take a look.

Regards,

Tony

^ permalink raw reply

* Re: [PATCH v6 8/9] net/mlx5: Do not call pcie_print_link_status()
From: Tal Gilboa @ 2018-08-08 15:56 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: Alexandru Gagniuc, linux-pci, bhelgaas, jakub.kicinski,
	keith.busch, alex_gagniuc, austin_bolen, shyam_iyer, Ariel Elior,
	everest-linux-l2, David S. Miller, Michael Chan, Ganesh Goudar,
	Jeff Kirsher, Tariq Toukan, Saeed Mahameed, Dirk van der Merwe,
	netdev, linux-kernel, intel-wired-lan, linux-rdma, oss-drivers
In-Reply-To: <20180808154142.GZ13378@mtr-leonro.mtl.com>

On 8/8/2018 6:41 PM, Leon Romanovsky wrote:
> On Wed, Aug 08, 2018 at 05:23:12PM +0300, Tal Gilboa wrote:
>> On 8/8/2018 9:08 AM, Leon Romanovsky wrote:
>>> On Mon, Aug 06, 2018 at 06:25:42PM -0500, Alexandru Gagniuc wrote:
>>>> This is now done by the PCI core to warn of sub-optimal bandwidth.
>>>>
>>>> Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
>>>> ---
>>>>    drivers/net/ethernet/mellanox/mlx5/core/main.c | 4 ----
>>>>    1 file changed, 4 deletions(-)
>>>>
>>>
>>> Thanks,
>>> Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
>>>
>>
>> Alex,
>> I loaded mlx5 driver with and without these series. The report in dmesg is
>> now missing. From what I understood, the status should be reported at least
>> once, even if everything is in order.
> 
> It is not what this series is doing and it removes prints completely if
> fabric can deliver more than card is capable.
> 
>> We need this functionality to stay.
> 
> I'm not sure that you need this information in driver's dmesg output,
> but most probably something globally visible and accessible per-pci
> device.

Currently we have users that look for it. If we remove the dmesg print 
we need this to be reported elsewhere. Adding it to sysfs for example 
should be a valid solution for our case.

> 
>>
>> net-next (dmesg output for 07:00.0):
>> [270498.625351] mlx5_core 0000:07:00.0: firmware version: 14.22.4020
>> [270498.632130] mlx5_core 0000:07:00.0: 63.008 Gb/s available PCIe bandwidth
>> (8 GT/s x8 link)
>> [270499.169533] (0000:07:00.0): E-Switch: Total vports 9, per vport: max
>> uc(1024) max mc(16384)
>> [270499.182358] mlx5_core 0000:07:00.0: Port module event: module 0, Cable
>> plugged
>>
>> net-next + patches (dmesg output for 07:00.0):
>> [  331.608472] mlx5_core 0000:07:00.0: firmware version: 14.22.4020
>> [  332.564938] (0000:07:00.0): E-Switch: Total vports 9, per vport: max
>> uc(1024) max mc(16384)
>> [  332.616271] mlx5_core 0000:07:00.0: Port module event: module 0, Cable
>> plugged
>>
>>

^ permalink raw reply

* Re: [PATCH 00/28] at24: remove at24_platform_data
From: Wolfram Sang @ 2018-08-08 15:55 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

[-- Attachment #1: Type: text/plain, Size: 851 bytes --]

On Wed, Aug 08, 2018 at 05:31:22PM +0200, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> 
> This is a follow-up to the previously rejected series[1] which partially
> removed the at24_platform_data structure. After further development and
> taking reviews into account, this series finally removes that struct
> completely but not without touching many different parts of the code
> base.
> 
> Since I took over maintainership of the at24 driver I've been working
> towards removing at24_platform_data in favor for device properties.

Wooha, nice work. I can't really comment on it but wondered how you want
to upstream it (after reviews)? Pull request of an immutable branch for
nvmem-tree sounds best to me. Then I could also pull it in if i2c needs
it. Probably same situation for arm-soc...


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: Is it currently possible to connect SFP to dsa port?
From: Russell King - ARM Linux @ 2018-08-08 13:29 UTC (permalink / raw)
  To: Marek Behún; +Cc: Andrew Lunn, netdev
In-Reply-To: <20180808150013.250727c7@dellmb.labs.office.nic.cz>

On Wed, Aug 08, 2018 at 03:00:13PM +0200, Marek Behún wrote:
> Btw: some SFP modules can operate in 2500BASE-X mode. Currently the SFP
> driver does not support this, and there even isn't code in the
> mainline kernel for mvneta to switch to 2500BASEX. On Armada 3720 this
> has to be done by configuring comphy, which is currently done in
> u-boot. As a side project I am working on supporting Armada 3720 comphy
> in the kernel, so that it will be possible to set 2500BASE-X mode.

With mvneta, it works the same way as other Marvell stuff - the comphy
needs to be told to up-clock the 1000base-X to 2500base-X.  That's all
that 2500base-X is - an up-clocked 1000base-X.

With Armada 388, it's just a matter of poking one register to configure
the comphy to 2500base-X.

As mvneta has no support for comphys, and I don't have the full details
for the comphy stuff, I've not bothered implementing anything for mvneta
other than some bare bones support in my repository to support the mode,
and resorting to poking the comphy register with devmem2 as required.

However, I can assure you that SFP definitely does support 2500base-X.
As 2500base-X is rather unofficial (there's no 802.3 standard for it)
there's no bits in SFP module eeprom that identify a module as
supporting this mode.

Consequently, the only way I'm aware of is to detect a Fibrechannel
SFP which supports the range of bitrates that would allow this mode
to work.  Currently, the code does this:

        /* For fibre channel SFP, derive possible BaseX modes */
        if (id->base.fc_speed_100 ||
            id->base.fc_speed_200 ||
            id->base.fc_speed_400) {
                if (id->base.br_nominal >= 31)
                        phylink_set(modes, 2500baseX_Full);
                if (id->base.br_nominal >= 12)
                        phylink_set(modes, 1000baseX_Full);
        }

So, the SFP core supports it.  What's expected from network drivers is
that they say they support 2500base-X, and then things get rather icky.
There is no way to autonegotiate between 2500base-X and 1000base-X.

What results is ultimately up to the driver implementation, but how I
have it locally via a local "phylink: add helper for configuring
2500BaseX modes" commit is:

- report 2500baseX_Full and 1000baseX_Full as supported to userspace.
- if both 2500baseX_Full and 1000baseX_Full are attempted to be set
   as advertised modes, clear 1000baseX_Full.
- select PHY_INTERFACE_MODE_2500BASEX or PHY_INTERFACE_MODE_1000BASEX
   depending whether the resulting advertising mask wants 2500baseX_Full
   or 1000baseX_Full.  If manual speed configuration, select between
   the PHY interface modes according to the requested speed.

With the exception of this commit (which is probably going to provoke
discussion about exactly what semantics we want) the SFP and phylink
code is all in place to support 2500base-X - I've proved it out using
a Macchiatobin (with the Marvell mvpp2x driver) and a Clearfog.

Without this patch, we detect in sfp_parse_support() that the module
is capable of 2500base-X, and, provided the network interface supports
2500base-X, sfp_select_interface() will select the 2500base-X PHY
interface mode, otherwise it'll select 1000base-X mode.

> The mv88e6190/6390 can configure ports 9 and 10 to either
> 1000BASE-X/SGMII od 2500BASE-X, but this has to be done by setting a
> pin and reseting the switch. Our board is able to configure this pin,
> and the plan is to do this in u-boot when SFP board is detected to be
> connected to the switch board. In this case the port is configured to
> 1000BASE-X.

It's really not that simple, unfortunately.  If you are talking about
pluggable SFPs (btw, SFP itself means the hot-pluggable modules, not
the soldered down modules, although we support both), SFP modules can
require *either* 1000base-X or SGMII.  There are some copper modules
with a PHY on board that want 1000base-X, but the vast majority of
copper modules want SGMII.  Conversely, gigabit fiber modules want
1000base-X.

Even more annoying, there is nothing that definitively tells you which
mode you should be using - and if you use the wrong mode, it may or
may not work, and you may or may not end up with a mismatched config
at either end of the link.

So, merely detecting a SFP modules presence doesn't tell you which
mode you should be in - and the annoying part is, if you hotplug the
module, you might need to change the port mode.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 13.8Mbps down 630kbps up
According to speedtest.net: 13Mbps down 490kbps up

^ permalink raw reply

* Re: [PATCH bpf-next 12/13] docs: net: Fix various minor typos
From: Jonathan Corbet @ 2018-08-08 13:23 UTC (permalink / raw)
  To: Tobin C. Harding
  Cc: Daniel Borkmann, Alexei Starovoitov, David S. Miller, linux-doc,
	netdev, linux-kernel
In-Reply-To: <20180808014248.GF11191@eros>

On Wed, 8 Aug 2018 11:42:48 +1000
"Tobin C. Harding" <me@tobin.cc> wrote:

> Hi Daniel,
> 
> Thanks for doing such a careful review that you noticed this.  I'm
> working on this more ATM and I've moved the document to use double
> spaces between _all_ full stops.  Currently the document uses mostly
> single spaces but there are some sections with double space.  The
> internet tells me this is a 'style' issue not a rule.  And I've seen
> single and double spacing in tree and do not know if one is favoured.
> 
> Do you care? 

I'm not Daniel, but let me just say that, for docs in general, I'm
absolutely uninterested in patches adjusting the number of spaces after
periods.  It really doesn't matter one way or the other, and I don't think
we benefit from that kind of churn.

Thanks,

jon

^ permalink raw reply

* Re: [PATCH v6 8/9] net/mlx5: Do not call pcie_print_link_status()
From: Leon Romanovsky @ 2018-08-08 15:41 UTC (permalink / raw)
  To: Tal Gilboa
  Cc: Alexandru Gagniuc, linux-pci, bhelgaas, jakub.kicinski,
	keith.busch, alex_gagniuc, austin_bolen, shyam_iyer, Ariel Elior,
	everest-linux-l2, David S. Miller, Michael Chan, Ganesh Goudar,
	Jeff Kirsher, Tariq Toukan, Saeed Mahameed, Dirk van der Merwe,
	netdev, linux-kernel, intel-wired-lan, linux-rdma, oss-drivers
In-Reply-To: <05056a70-ee78-ea3c-0b9b-6d64a8663b11@mellanox.com>

[-- Attachment #1: Type: text/plain, Size: 1730 bytes --]

On Wed, Aug 08, 2018 at 05:23:12PM +0300, Tal Gilboa wrote:
> On 8/8/2018 9:08 AM, Leon Romanovsky wrote:
> > On Mon, Aug 06, 2018 at 06:25:42PM -0500, Alexandru Gagniuc wrote:
> > > This is now done by the PCI core to warn of sub-optimal bandwidth.
> > >
> > > Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
> > > ---
> > >   drivers/net/ethernet/mellanox/mlx5/core/main.c | 4 ----
> > >   1 file changed, 4 deletions(-)
> > >
> >
> > Thanks,
> > Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
> >
>
> Alex,
> I loaded mlx5 driver with and without these series. The report in dmesg is
> now missing. From what I understood, the status should be reported at least
> once, even if everything is in order.

It is not what this series is doing and it removes prints completely if
fabric can deliver more than card is capable.

> We need this functionality to stay.

I'm not sure that you need this information in driver's dmesg output,
but most probably something globally visible and accessible per-pci
device.

>
> net-next (dmesg output for 07:00.0):
> [270498.625351] mlx5_core 0000:07:00.0: firmware version: 14.22.4020
> [270498.632130] mlx5_core 0000:07:00.0: 63.008 Gb/s available PCIe bandwidth
> (8 GT/s x8 link)
> [270499.169533] (0000:07:00.0): E-Switch: Total vports 9, per vport: max
> uc(1024) max mc(16384)
> [270499.182358] mlx5_core 0000:07:00.0: Port module event: module 0, Cable
> plugged
>
> net-next + patches (dmesg output for 07:00.0):
> [  331.608472] mlx5_core 0000:07:00.0: firmware version: 14.22.4020
> [  332.564938] (0000:07:00.0): E-Switch: Total vports 9, per vport: max
> uc(1024) max mc(16384)
> [  332.616271] mlx5_core 0000:07:00.0: Port module event: module 0, Cable
> plugged
>
>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: [PATCH wireless-drivers] mt76x0: Remove VLA usage
From: Kees Cook @ 2018-08-08 15:41 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Stanislaw Gruszka, David S. Miller, linux-wireless,
	Network Development, LKML
In-Reply-To: <871sb942cx.fsf@kamboji.qca.qualcomm.com>

On Wed, Aug 8, 2018 at 2:46 AM, Kalle Valo <kvalo@codeaurora.org> wrote:
> Stanislaw Gruszka <sgruszka@redhat.com> writes:
>
>> On Tue, Aug 07, 2018 at 03:50:40PM -0700, Kees Cook wrote:
>>> Even with "const" variables, the compiler will generate warnings about
>>> VLA usage. In the quest to remove all VLAs from the kernel[1], this uses
>>> a #define instead of a const to do the array sizing.
>>>
>>> [1]
>>> https://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qPXydAacU1RqZWA@mail.gmail.com
>>>
>>> Fixes: e87b5039511a ("mt76x0: eeprom files")
>>> Signed-off-by: Kees Cook <keescook@chromium.org>
>>> ---
>>> Please include this for the v4.19 merge window. The VLA was introduced
>>> with the new source file (which I also note is missing a SPDX line), so
>>
>> I thought SPDX line is needed only if file has no license and eeprom.c
>> file and other mt76x0 files have specified the license. Is SPDX still
>> needed in that case ?

I thought all source files needed SPDX: https://lwn.net/Articles/739183/

>>
>>> +#define MT_MAP_READS        DIV_ROUND_UP(MT_EFUSE_USAGE_MAP_SIZE, 16)
>>>  static int
>>>  mt76x0_efuse_physical_size_check(struct mt76x0_dev *dev)
>>>  {
>>> -    const int map_reads = DIV_ROUND_UP(MT_EFUSE_USAGE_MAP_SIZE, 16);
>>> -    u8 data[map_reads * 16];
>>
>> Why this is variable length array? DIV_ROUND_UP can not be calculated
>> at compile time? But if so, macro do not change the situation either.
>
> The commit log mentioned:
>
>   "Even with "const" variables, the compiler will generate warnings about
>    VLA usage."
>
> So I guess the compiler (gcc?) is just not smart enough in this case?

Correct. This is technically a false positive, but with the goal of
adding -Wvla to the build globally, we have to get rid of these as
well. It's a little frustrating, I agree, but with all others fixed
now, these stand out. :)

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply

* [PATCH 28/28] eeprom: at24: kill at24_platform_data
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

There are no more users of at24_platform_data. Remove the relevant
header and modify the driver code to not use it anymore.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 MAINTAINERS                        |   1 -
 drivers/misc/eeprom/at24.c         | 127 +++++++++++++----------------
 include/linux/platform_data/at24.h |  60 --------------
 3 files changed, 57 insertions(+), 131 deletions(-)
 delete mode 100644 include/linux/platform_data/at24.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 7cebd5bba8a8..8eb87a3548f8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2328,7 +2328,6 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git
 S:	Maintained
 F:	Documentation/devicetree/bindings/eeprom/at24.txt
 F:	drivers/misc/eeprom/at24.c
-F:	include/linux/platform_data/at24.h
 
 ATA OVER ETHERNET (AOE) DRIVER
 M:	"Ed L. Cashin" <ed.cashin@acm.org>
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index f5cc517d1131..93642b4b47c5 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -22,10 +22,24 @@
 #include <linux/i2c.h>
 #include <linux/nvmem-provider.h>
 #include <linux/regmap.h>
-#include <linux/platform_data/at24.h>
 #include <linux/pm_runtime.h>
 #include <linux/gpio/consumer.h>
 
+/* Address pointer is 16 bit. */
+#define AT24_FLAG_ADDR16	BIT(7)
+/* sysfs-entry will be read-only. */
+#define AT24_FLAG_READONLY	BIT(6)
+/* sysfs-entry will be world-readable. */
+#define AT24_FLAG_IRUGO		BIT(5)
+/* Take always 8 addresses (24c00). */
+#define AT24_FLAG_TAKE8ADDR	BIT(4)
+/* Factory-programmed serial number. */
+#define AT24_FLAG_SERIAL	BIT(3)
+/* Factory-programmed mac address. */
+#define AT24_FLAG_MAC		BIT(2)
+/* Does not auto-rollover reads to the next slave address. */
+#define AT24_FLAG_NO_RDROL	BIT(1)
+
 /*
  * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable.
  * Differences between different vendor product lines (like Atmel AT24C or
@@ -124,10 +138,6 @@ MODULE_PARM_DESC(at24_write_timeout, "Time (in ms) to try writes (default 25)");
 	     usleep_range(1000, 1500), op_time = jiffies)
 
 struct at24_chip_data {
-	/*
-	 * these fields mirror their equivalents in
-	 * struct at24_platform_data
-	 */
 	u32 byte_len;
 	u8 flags;
 };
@@ -467,46 +477,11 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count)
 	return 0;
 }
 
-static void at24_properties_to_pdata(struct device *dev,
-				     struct at24_platform_data *chip)
-{
-	int err;
-	u32 val;
-
-	if (device_property_present(dev, "read-only"))
-		chip->flags |= AT24_FLAG_READONLY;
-	if (device_property_present(dev, "no-read-rollover"))
-		chip->flags |= AT24_FLAG_NO_RDROL;
-
-	err = device_property_read_u32(dev, "size", &val);
-	if (!err)
-		chip->byte_len = val;
-
-	err = device_property_read_u32(dev, "pagesize", &val);
-	if (!err) {
-		chip->page_size = val;
-	} else {
-		/*
-		 * This is slow, but we can't know all eeproms, so we better
-		 * play safe. Specifying custom eeprom-types via platform_data
-		 * is recommended anyhow.
-		 */
-		chip->page_size = 1;
-	}
-}
-
-static int at24_get_pdata(struct device *dev, struct at24_platform_data *pdata)
+static const struct at24_chip_data *at24_get_chip_data(struct device *dev)
 {
 	struct device_node *of_node = dev->of_node;
 	const struct at24_chip_data *cdata;
 	const struct i2c_device_id *id;
-	struct at24_platform_data *pd;
-
-	pd = dev_get_platdata(dev);
-	if (pd) {
-		memcpy(pdata, pd, sizeof(*pdata));
-		return 0;
-	}
 
 	id = i2c_match_id(at24_ids, to_i2c_client(dev));
 
@@ -523,13 +498,9 @@ static int at24_get_pdata(struct device *dev, struct at24_platform_data *pdata)
 		cdata = acpi_device_get_match_data(dev);
 
 	if (!cdata)
-		return -ENODEV;
+		return ERR_PTR(-ENODEV);
 
-	pdata->byte_len = cdata->byte_len;
-	pdata->flags = cdata->flags;
-	at24_properties_to_pdata(dev, pdata);
-
-	return 0;
+	return cdata;
 }
 
 static void at24_remove_dummy_clients(struct at24_data *at24)
@@ -598,8 +569,9 @@ static int at24_probe(struct i2c_client *client)
 {
 	struct regmap_config regmap_config = { };
 	struct nvmem_config nvmem_config = { };
-	struct at24_platform_data pdata = { };
+	const struct at24_chip_data *cdata;
 	struct device *dev = &client->dev;
+	u32 byte_len, page_size, flags;
 	bool i2c_fn_i2c, i2c_fn_block;
 	unsigned int i, num_addresses;
 	struct at24_data *at24;
@@ -613,35 +585,54 @@ static int at24_probe(struct i2c_client *client)
 	i2c_fn_block = i2c_check_functionality(client->adapter,
 					       I2C_FUNC_SMBUS_WRITE_I2C_BLOCK);
 
-	err = at24_get_pdata(dev, &pdata);
+	cdata = at24_get_chip_data(dev);
+	if (IS_ERR(cdata))
+		return PTR_ERR(cdata);
+
+	err = device_property_read_u32(dev, "pagesize", &page_size);
+	if (err)
+		/*
+		 * This is slow, but we can't know all eeproms, so we better
+		 * play safe. Specifying custom eeprom-types via platform_data
+		 * is recommended anyhow.
+		 */
+		page_size = 1;
+
+	flags = cdata->flags;
+	if (device_property_present(dev, "read-only"))
+		flags |= AT24_FLAG_READONLY;
+	if (device_property_present(dev, "no-read-rollover"))
+		flags |= AT24_FLAG_NO_RDROL;
+
+	err = device_property_read_u32(dev, "size", &byte_len);
 	if (err)
-		return err;
+		byte_len = cdata->byte_len;
 
 	if (!i2c_fn_i2c && !i2c_fn_block)
-		pdata.page_size = 1;
+		page_size = 1;
 
-	if (!pdata.page_size) {
+	if (!page_size) {
 		dev_err(dev, "page_size must not be 0!\n");
 		return -EINVAL;
 	}
 
-	if (!is_power_of_2(pdata.page_size))
+	if (!is_power_of_2(page_size))
 		dev_warn(dev, "page_size looks suspicious (no power of 2)!\n");
 
-	if (pdata.flags & AT24_FLAG_TAKE8ADDR)
+	if (flags & AT24_FLAG_TAKE8ADDR)
 		num_addresses = 8;
 	else
-		num_addresses =	DIV_ROUND_UP(pdata.byte_len,
-			(pdata.flags & AT24_FLAG_ADDR16) ? 65536 : 256);
+		num_addresses =	DIV_ROUND_UP(byte_len,
+			(flags & AT24_FLAG_ADDR16) ? 65536 : 256);
 
-	if ((pdata.flags & AT24_FLAG_SERIAL) && (pdata.flags & AT24_FLAG_MAC)) {
+	if ((flags & AT24_FLAG_SERIAL) && (flags & AT24_FLAG_MAC)) {
 		dev_err(dev,
 			"invalid device data - cannot have both AT24_FLAG_SERIAL & AT24_FLAG_MAC.");
 		return -EINVAL;
 	}
 
 	regmap_config.val_bits = 8;
-	regmap_config.reg_bits = (pdata.flags & AT24_FLAG_ADDR16) ? 16 : 8;
+	regmap_config.reg_bits = (flags & AT24_FLAG_ADDR16) ? 16 : 8;
 	regmap_config.disable_locking = true;
 
 	regmap = devm_regmap_init_i2c(client, &regmap_config);
@@ -654,11 +645,11 @@ static int at24_probe(struct i2c_client *client)
 		return -ENOMEM;
 
 	mutex_init(&at24->lock);
-	at24->byte_len = pdata.byte_len;
-	at24->page_size = pdata.page_size;
-	at24->flags = pdata.flags;
+	at24->byte_len = byte_len;
+	at24->page_size = page_size;
+	at24->flags = flags;
 	at24->num_addresses = num_addresses;
-	at24->offset_adj = at24_get_offset_adj(pdata.flags, pdata.byte_len);
+	at24->offset_adj = at24_get_offset_adj(flags, byte_len);
 	at24->client[0].client = client;
 	at24->client[0].regmap = regmap;
 
@@ -666,10 +657,10 @@ static int at24_probe(struct i2c_client *client)
 	if (IS_ERR(at24->wp_gpio))
 		return PTR_ERR(at24->wp_gpio);
 
-	writable = !(pdata.flags & AT24_FLAG_READONLY);
+	writable = !(flags & AT24_FLAG_READONLY);
 	if (writable) {
 		at24->write_max = min_t(unsigned int,
-					pdata.page_size, at24_io_limit);
+					page_size, at24_io_limit);
 		if (!i2c_fn_i2c && at24->write_max > I2C_SMBUS_BLOCK_MAX)
 			at24->write_max = I2C_SMBUS_BLOCK_MAX;
 	}
@@ -712,7 +703,7 @@ static int at24_probe(struct i2c_client *client)
 	nvmem_config.priv = at24;
 	nvmem_config.stride = 1;
 	nvmem_config.word_size = 1;
-	nvmem_config.size = pdata.byte_len;
+	nvmem_config.size = byte_len;
 
 	at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
 	if (IS_ERR(at24->nvmem)) {
@@ -721,13 +712,9 @@ static int at24_probe(struct i2c_client *client)
 	}
 
 	dev_info(dev, "%u byte %s EEPROM, %s, %u bytes/write\n",
-		 pdata.byte_len, client->name,
+		 byte_len, client->name,
 		 writable ? "writable" : "read-only", at24->write_max);
 
-	/* export data to kernel code */
-	if (pdata.setup)
-		pdata.setup(at24->nvmem, pdata.context);
-
 	return 0;
 
 err_clients:
diff --git a/include/linux/platform_data/at24.h b/include/linux/platform_data/at24.h
deleted file mode 100644
index 63507ff464ee..000000000000
--- a/include/linux/platform_data/at24.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * at24.h - platform_data for the at24 (generic eeprom) driver
- * (C) Copyright 2008 by Pengutronix
- * (C) Copyright 2012 by Wolfram Sang
- * same license as the driver
- */
-
-#ifndef _LINUX_AT24_H
-#define _LINUX_AT24_H
-
-#include <linux/types.h>
-#include <linux/nvmem-consumer.h>
-#include <linux/bitops.h>
-
-/**
- * struct at24_platform_data - data to set up at24 (generic eeprom) driver
- * @byte_len: size of eeprom in byte
- * @page_size: number of byte which can be written in one go
- * @flags: tunable options, check AT24_FLAG_* defines
- * @setup: an optional callback invoked after eeprom is probed; enables kernel
-	code to access eeprom via nvmem, see example
- * @context: optional parameter passed to setup()
- *
- * If you set up a custom eeprom type, please double-check the parameters.
- * Especially page_size needs extra care, as you risk data loss if your value
- * is bigger than what the chip actually supports!
- *
- * An example in pseudo code for a setup() callback:
- *
- * void get_mac_addr(struct nvmem_device *nvmem, void *context)
- * {
- *	u8 *mac_addr = ethernet_pdata->mac_addr;
- *	off_t offset = context;
- *
- *	// Read MAC addr from EEPROM
- *	if (nvmem_device_read(nvmem, offset, ETH_ALEN, mac_addr) == ETH_ALEN)
- *		pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr);
- * }
- *
- * This function pointer and context can now be set up in at24_platform_data.
- */
-
-struct at24_platform_data {
-	u32		byte_len;		/* size (sum of all addr) */
-	u16		page_size;		/* for writes */
-	u8		flags;
-#define AT24_FLAG_ADDR16	BIT(7)	/* address pointer is 16 bit */
-#define AT24_FLAG_READONLY	BIT(6)	/* sysfs-entry will be read-only */
-#define AT24_FLAG_IRUGO		BIT(5)	/* sysfs-entry will be world-readable */
-#define AT24_FLAG_TAKE8ADDR	BIT(4)	/* take always 8 addresses (24c00) */
-#define AT24_FLAG_SERIAL	BIT(3)	/* factory-programmed serial number */
-#define AT24_FLAG_MAC		BIT(2)	/* factory-programmed mac address */
-#define AT24_FLAG_NO_RDROL	BIT(1)	/* does not auto-rollover reads to */
-					/* the next slave address */
-
-	void		(*setup)(struct nvmem_device *nvmem, void *context);
-	void		*context;
-};
-
-#endif /* _LINUX_AT24_H */
-- 
2.18.0

^ permalink raw reply related

* [PATCH 25/28] ARM: davinci: remove dead code related to MAC address reading
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

There are no more users of davinci_get_mac_addr(). Remove it. Also
remove the mac_addr field from the emac platform data struct.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 arch/arm/mach-davinci/common.c | 15 ---------------
 include/linux/davinci_emac.h   |  2 --
 2 files changed, 17 deletions(-)

diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
index bcb6a7ba84e9..0c6cc354a4aa 100644
--- a/arch/arm/mach-davinci/common.c
+++ b/arch/arm/mach-davinci/common.c
@@ -28,21 +28,6 @@ EXPORT_SYMBOL(davinci_soc_info);
 void __iomem *davinci_intc_base;
 int davinci_intc_type;
 
-void davinci_get_mac_addr(struct nvmem_device *nvmem, void *context)
-{
-	char *mac_addr = davinci_soc_info.emac_pdata->mac_addr;
-	off_t offset = (off_t)context;
-
-	if (!IS_BUILTIN(CONFIG_NVMEM)) {
-		pr_warn("Cannot read MAC addr from EEPROM without CONFIG_NVMEM\n");
-		return;
-	}
-
-	/* Read MAC addr from EEPROM */
-	if (nvmem_device_read(nvmem, offset, ETH_ALEN, mac_addr) == ETH_ALEN)
-		pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr);
-}
-
 static int __init davinci_init_id(struct davinci_soc_info *soc_info)
 {
 	int			i;
diff --git a/include/linux/davinci_emac.h b/include/linux/davinci_emac.h
index 05b97144d342..19888b27706d 100644
--- a/include/linux/davinci_emac.h
+++ b/include/linux/davinci_emac.h
@@ -19,7 +19,6 @@ struct mdio_platform_data {
 };
 
 struct emac_platform_data {
-	char mac_addr[ETH_ALEN];
 	u32 ctrl_reg_offset;
 	u32 ctrl_mod_reg_offset;
 	u32 ctrl_ram_offset;
@@ -46,5 +45,4 @@ enum {
 	EMAC_VERSION_2,	/* DM646x */
 };
 
-void davinci_get_mac_addr(struct nvmem_device *nvmem, void *context);
 #endif
-- 
2.18.0

^ permalink raw reply related

* [PATCH 21/28] ARM: davinci: dm644x-evm: use device properties for at24 eeprom
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

We want to work towards phasing out the at24_platform_data structure.
There are few users and its contents can be represented using generic
device properties. Using device properties only will allow us to
significantly simplify the at24 configuration code.

Remove the at24_platform_data structure and replace it with an array
of property entries. Drop the byte_len/size property, as the model name
already implies the EEPROM's size.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 arch/arm/mach-davinci/board-dm644x-evm.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 6d35c6e1b0bd..abfcf42da6fb 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -16,8 +16,8 @@
 #include <linux/gpio/machine.h>
 #include <linux/i2c.h>
 #include <linux/platform_data/pcf857x.h>
-#include <linux/platform_data/at24.h>
 #include <linux/platform_data/gpio-davinci.h>
+#include <linux/property.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/partitions.h>
@@ -486,12 +486,8 @@ static struct nvmem_cell_lookup dm6446evm_mac_address_cell = {
 	.nvmem_name = "1-00500",
 };
 
-static struct at24_platform_data eeprom_info = {
-	.byte_len	= (256*1024) / 8,
-	.page_size	= 64,
-	.flags		= AT24_FLAG_ADDR16,
-	.setup          = davinci_get_mac_addr,
-	.context	= (void *)0x7f00,
+static const struct property_entry eeprom_properties[] = {
+	PROPERTY_ENTRY_U32("pagesize", 64),
 };
 
 /*
@@ -601,7 +597,7 @@ static struct i2c_board_info __initdata i2c_info[] =  {
 	},
 	{
 		I2C_BOARD_INFO("24c256", 0x50),
-		.platform_data	= &eeprom_info,
+		.properties = eeprom_properties,
 	},
 	{
 		I2C_BOARD_INFO("tlv320aic33", 0x1b),
-- 
2.18.0

^ permalink raw reply related

* [PATCH 19/28] ARM: davinci: dm365-evm: use device properties for at24 eeprom
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

We want to work towards phasing out the at24_platform_data structure.
There are few users and its contents can be represented using generic
device properties. Using device properties only will allow us to
significantly simplify the at24 configuration code.

Remove the at24_platform_data structure and replace it with an array
of property entries. Drop the byte_len/size property, as the model name
already implies the EEPROM's size.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 arch/arm/mach-davinci/board-dm365-evm.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index cb0ac92a278e..b360d26e6caa 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -18,7 +18,7 @@
 #include <linux/i2c.h>
 #include <linux/io.h>
 #include <linux/clk.h>
-#include <linux/platform_data/at24.h>
+#include <linux/property.h>
 #include <linux/leds.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -179,18 +179,15 @@ static struct nvmem_cell_lookup dm365evm_mac_address_cell = {
 	.nvmem_name = "1-00500",
 };
 
-static struct at24_platform_data eeprom_info = {
-	.byte_len       = (256*1024) / 8,
-	.page_size      = 64,
-	.flags          = AT24_FLAG_ADDR16,
-	.setup          = davinci_get_mac_addr,
-	.context	= (void *)0x7f00,
+static const struct property_entry eeprom_properties[] = {
+	PROPERTY_ENTRY_U32("pagesize", 64),
+	{ }
 };
 
 static struct i2c_board_info i2c_info[] = {
 	{
 		I2C_BOARD_INFO("24c256", 0x50),
-		.platform_data	= &eeprom_info,
+		.properties = eeprom_properties,
 	},
 	{
 		I2C_BOARD_INFO("tlv320aic3x", 0x18),
-- 
2.18.0

^ permalink raw reply related

* [PATCH 17/28] ARM: davinci: da850-evm: remove dead MTD code
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

We no longer need to register the MTD notifier to read the MAC address
as it's now being done in the emac driver.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 arch/arm/mach-davinci/board-da850-evm.c | 28 -------------------------
 1 file changed, 28 deletions(-)

diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 521a26b5c20d..1df796b67b82 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -137,32 +137,6 @@ static struct spi_board_info da850evm_spi_info[] = {
 	},
 };
 
-#ifdef CONFIG_MTD
-static void da850_evm_m25p80_notify_add(struct mtd_info *mtd)
-{
-	char *mac_addr = davinci_soc_info.emac_pdata->mac_addr;
-	size_t retlen;
-
-	if (!strcmp(mtd->name, "MAC-Address")) {
-		mtd_read(mtd, 0, ETH_ALEN, &retlen, mac_addr);
-		if (retlen == ETH_ALEN)
-			pr_info("Read MAC addr from SPI Flash: %pM\n",
-				mac_addr);
-	}
-}
-
-static struct mtd_notifier da850evm_spi_notifier = {
-	.add	= da850_evm_m25p80_notify_add,
-};
-
-static void da850_evm_setup_mac_addr(void)
-{
-	register_mtd_user(&da850evm_spi_notifier);
-}
-#else
-static void da850_evm_setup_mac_addr(void) { }
-#endif
-
 static struct mtd_partition da850_evm_norflash_partition[] = {
 	{
 		.name           = "bootloaders + env",
@@ -1470,8 +1444,6 @@ static __init void da850_evm_init(void)
 	if (ret)
 		pr_warn("%s: SATA registration failed: %d\n", __func__, ret);
 
-	da850_evm_setup_mac_addr();
-
 	ret = da8xx_register_rproc();
 	if (ret)
 		pr_warn("%s: dsp/rproc registration failed: %d\n",
-- 
2.18.0

^ permalink raw reply related

* [PATCH 16/28] net: davinci_emac: use eth_platform_get_mac_address()
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

We now support nvmem in eth_platform_get_mac_address() and all boards
have the mac-address cells defined. Stop getting the MAC from pdata
and use the dedicated helper.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/net/ethernet/ti/davinci_emac.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index f270beebb428..5d01bad4baa5 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -1700,7 +1700,6 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv)
 	const struct of_device_id *match;
 	const struct emac_platform_data *auxdata;
 	struct emac_platform_data *pdata = NULL;
-	const u8 *mac_addr;
 
 	if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node)
 		return dev_get_platdata(&pdev->dev);
@@ -1712,12 +1711,6 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv)
 	np = pdev->dev.of_node;
 	pdata->version = EMAC_VERSION_2;
 
-	if (!is_valid_ether_addr(pdata->mac_addr)) {
-		mac_addr = of_get_mac_address(np);
-		if (mac_addr)
-			ether_addr_copy(pdata->mac_addr, mac_addr);
-	}
-
 	of_property_read_u32(np, "ti,davinci-ctrl-reg-offset",
 			     &pdata->ctrl_reg_offset);
 
@@ -1819,8 +1812,11 @@ static int davinci_emac_probe(struct platform_device *pdev)
 		goto err_free_netdev;
 	}
 
+	rc = eth_platform_get_mac_address(&pdev->dev, priv->mac_addr);
+	if (rc == -EPROBE_DEFER)
+		return -EPROBE_DEFER; /* We'll get the MAC address later. */
+
 	/* MAC addr and PHY mask , RMII enable info from platform_data */
-	memcpy(priv->mac_addr, pdata->mac_addr, ETH_ALEN);
 	priv->phy_id = pdata->phy_id;
 	priv->rmii_en = pdata->rmii_en;
 	priv->version = pdata->version;
-- 
2.18.0

^ permalink raw reply related

* [PATCH 15/28] net: add support for nvmem to eth_platform_get_mac_address()
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Many non-DT platforms read the MAC address from EEPROM. Usually it's
either done with callbacks defined in board files or from SoC-specific
ethernet drivers.

In order to generalize this, try to read the MAC from nvmem in
eth_platform_get_mac_address() using a standard lookup name:
"mac-address".

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 net/ethernet/eth.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index cf54cdf042b7..98bc280b8a62 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -54,6 +54,7 @@
 #include <linux/if_ether.h>
 #include <linux/of_net.h>
 #include <linux/pci.h>
+#include <linux/nvmem-consumer.h>
 #include <net/dst.h>
 #include <net/arp.h>
 #include <net/sock.h>
@@ -559,6 +560,39 @@ static int mac_address_from_arch(u8 *mac_addr)
 	return 0;
 }
 
+static int mac_address_from_nvmem(struct device *dev, u8 *mac_addr)
+{
+	const unsigned char *addr;
+	struct nvmem_cell *cell;
+	size_t alen;
+	int rv = 0;
+
+	cell = nvmem_cell_get(dev, "mac-address");
+	if (IS_ERR(cell))
+		return PTR_ERR(cell);
+
+	addr = nvmem_cell_read(cell, &alen);
+	if (IS_ERR(addr)) {
+		rv = PTR_ERR(addr);
+		goto put_nvmem;
+	}
+
+	if (alen != ETH_ALEN || !is_valid_ether_addr(addr)) {
+		rv = -ENODEV;
+		goto free_addr;
+	}
+
+	ether_addr_copy(mac_addr, addr);
+
+free_addr:
+	kfree(addr);
+
+put_nvmem:
+	nvmem_cell_put(cell);
+
+	return rv;
+}
+
 int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
 {
 	int rv;
@@ -571,6 +605,10 @@ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
 	if (!rv)
 		return 0;
 
+	rv = mac_address_from_nvmem(dev, mac_addr);
+	if (!rv)
+		return 0;
+
 	return -ENODEV;
 }
 EXPORT_SYMBOL(eth_platform_get_mac_address);
-- 
2.18.0

^ permalink raw reply related

* [PATCH 14/28] net: split eth_platform_get_mac_address() into subroutines
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

We want do add more sources from which to read the MAC address. In
order to avoid bloating this function too much, start by splitting it
into subroutines, each of which takes care of reading the MAC from
one source.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 net/ethernet/eth.c | 48 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 37 insertions(+), 11 deletions(-)

diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index ee28440f57c5..cf54cdf042b7 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -525,26 +525,52 @@ unsigned char * __weak arch_get_platform_mac_address(void)
 	return NULL;
 }
 
-int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
+static int mac_address_from_of(struct device *dev, u8 *mac_addr)
 {
 	const unsigned char *addr;
-	struct device_node *dp;
+	struct device_node *np;
 
-	if (dev_is_pci(dev))
-		dp = pci_device_to_OF_node(to_pci_dev(dev));
-	else
-		dp = dev->of_node;
+	np = dev_is_pci(dev) ? pci_device_to_OF_node(to_pci_dev(dev))
+			     : dev->of_node;
 
-	addr = NULL;
-	if (dp)
-		addr = of_get_mac_address(dp);
-	if (!addr)
-		addr = arch_get_platform_mac_address();
+	if (!np)
+		return -ENODEV;
 
+	addr = of_get_mac_address(np);
 	if (!addr)
 		return -ENODEV;
 
+	if (!addr || !is_valid_ether_addr(addr))
+		return -ENODEV;
+
+	ether_addr_copy(mac_addr, addr);
+	return 0;
+}
+
+static int mac_address_from_arch(u8 *mac_addr)
+{
+	const unsigned char *addr;
+
+	addr = arch_get_platform_mac_address();
+	if (!addr || !is_valid_ether_addr(addr))
+		return -ENODEV;
+
 	ether_addr_copy(mac_addr, addr);
 	return 0;
 }
+
+int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
+{
+	int rv;
+
+	rv = mac_address_from_of(dev, mac_addr);
+	if (!rv)
+		return 0;
+
+	rv = mac_address_from_arch(mac_addr);
+	if (!rv)
+		return 0;
+
+	return -ENODEV;
+}
 EXPORT_SYMBOL(eth_platform_get_mac_address);
-- 
2.18.0

^ permalink raw reply related

* [PATCH 13/28] ARM: davinci: da850-evm: remove unnecessary include
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

The include file for at24_platform_data is not needed in this file.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 arch/arm/mach-davinci/board-da850-evm.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 5a634a04ec69..521a26b5c20d 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -20,7 +20,6 @@
 #include <linux/kernel.h>
 #include <linux/leds.h>
 #include <linux/i2c.h>
-#include <linux/platform_data/at24.h>
 #include <linux/platform_data/pca953x.h>
 #include <linux/input.h>
 #include <linux/input/tps6507x-ts.h>
-- 
2.18.0

^ permalink raw reply related

* [PATCH 12/28] ARM: davinci: da850-evm: use nvmem lookup for mac address
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

We now support nvmem lookups for machine code. Add a lookup for
mac-address.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 arch/arm/mach-davinci/board-da850-evm.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 6d5beb11bd96..5a634a04ec69 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -29,6 +29,7 @@
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
+#include <linux/nvmem-provider.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/gpio-davinci.h>
 #include <linux/platform_data/mtd-davinci.h>
@@ -99,6 +100,19 @@ static struct mtd_partition da850evm_spiflash_part[] = {
 	},
 };
 
+static struct nvmem_cell_lookup da850evm_mac_address_cell = {
+	.info = {
+		.name = "mac-address",
+		.offset = 0x0,
+		.bytes = ETH_ALEN,
+	},
+	/*
+	 * The nvmem name differs from the partition name because of the
+	 * internal works of the nvmem framework.
+	 */
+	.nvmem_name = "MAC-Address0",
+};
+
 static struct flash_platform_data da850evm_spiflash_data = {
 	.name		= "m25p80",
 	.parts		= da850evm_spiflash_part,
@@ -1447,6 +1461,8 @@ static __init void da850_evm_init(void)
 		pr_warn("%s: spi info registration failed: %d\n", __func__,
 			ret);
 
+	nvmem_add_lookup_table(&da850evm_mac_address_cell, 1);
+
 	ret = da8xx_register_spi_bus(1, ARRAY_SIZE(da850evm_spi_info));
 	if (ret)
 		pr_warn("%s: SPI 1 registration failed: %d\n", __func__, ret);
-- 
2.18.0

^ permalink raw reply related

* [PATCH 11/28] ARM: davinci: mityomapl138: add nvmem cells lookup entries
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

We now support nvmem lookups for machine code. Add a lookup for
mac-address.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 arch/arm/mach-davinci/board-mityomapl138.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index 37b3e48a21d1..b5be51c0451e 100644
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -21,6 +21,7 @@
 #include <linux/etherdevice.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#include <linux/nvmem-provider.h>
 
 #include <asm/io.h>
 #include <asm/mach-types.h>
@@ -160,6 +161,25 @@ static void read_factory_config(struct nvmem_device *nvmem, void *context)
 	mityomapl138_cpufreq_init(partnum);
 }
 
+static struct nvmem_cell_lookup mityomapl138_nvmem_cells[] = {
+	{
+		.info = {
+			.name = "factory-config",
+			.offset = 0x0,
+			.bytes = sizeof(struct factory_config),
+		},
+		.nvmem_name = "1-00500",
+	},
+	{
+		.info = {
+			.name = "mac-address",
+			.offset = 0x64,
+			.bytes = ETH_ALEN,
+		},
+		.nvmem_name = "1-00500",
+	}
+};
+
 static struct at24_platform_data mityomapl138_fd_chip = {
 	.byte_len	= 256,
 	.page_size	= 8,
@@ -534,6 +554,8 @@ static void __init mityomapl138_init(void)
 	if (ret)
 		pr_warn("spi 1 registration failed: %d\n", ret);
 
+	nvmem_add_lookup_table(mityomapl138_nvmem_cells,
+			       ARRAY_SIZE(mityomapl138_nvmem_cells));
 	mityomapl138_config_emac();
 
 	ret = da8xx_register_rtc();
-- 
2.18.0

^ permalink raw reply related

* [PATCH 09/28] ARM: davinci: dm646x-evm: use nvmem lookup for mac address
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

We now support nvmem lookups for machine code. Add a lookup for
mac-address.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 arch/arm/mach-davinci/board-dm646x-evm.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index 584064fdabf5..5a9de47bc8a2 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -37,6 +37,7 @@
 #include <linux/platform_data/i2c-davinci.h>
 #include <linux/platform_data/mtd-davinci.h>
 #include <linux/platform_data/mtd-davinci-aemif.h>
+#include <linux/nvmem-provider.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -310,6 +311,15 @@ static struct pcf857x_platform_data pcf_data = {
  *  - ... newer boards may have more
  */
 
+static struct nvmem_cell_lookup dm646x_evm_mac_address_cell = {
+	.info = {
+		.name = "mac-address",
+		.offset = 0x7f00,
+		.bytes = ETH_ALEN,
+	},
+	.nvmem_name = "1-00500",
+};
+
 static struct at24_platform_data eeprom_info = {
 	.byte_len       = (256*1024) / 8,
 	.page_size      = 64,
@@ -802,6 +812,8 @@ static __init void evm_init(void)
 		davinci_init_ide();
 
 	soc_info->emac_pdata->phy_id = DM646X_EVM_PHY_ID;
+
+	nvmem_add_lookup_table(&dm646x_evm_mac_address_cell, 1);
 }
 
 MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
-- 
2.18.0

^ permalink raw reply related

* [PATCH 08/28] ARM: davinci: dm644-evm: use nvmem lookup for mac address
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter,
	Florian Fainelli, Ivan Khoronzhuk, Sven Van Asbroeck
  Cc: linux-doc, netdev, linux-kernel, Bartosz Golaszewski, linux-mtd,
	linux-i2c, linux-omap, linux-arm-kernel
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

We now support nvmem lookups for machine code. Add a lookup for
mac-address.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 arch/arm/mach-davinci/board-dm644x-evm.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 48436f74fd71..6d35c6e1b0bd 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -28,6 +28,7 @@
 #include <linux/v4l2-dv-timings.h>
 #include <linux/export.h>
 #include <linux/leds.h>
+#include <linux/nvmem-provider.h>
 
 #include <media/i2c/tvp514x.h>
 
@@ -476,6 +477,15 @@ static struct pcf857x_platform_data pcf_data_u35 = {
  *  - ... newer boards may have more
  */
 
+static struct nvmem_cell_lookup dm6446evm_mac_address_cell = {
+	.info = {
+		.name = "mac-address",
+		.offset = 0x7f00,
+		.bytes = ETH_ALEN,
+	},
+	.nvmem_name = "1-00500",
+};
+
 static struct at24_platform_data eeprom_info = {
 	.byte_len	= (256*1024) / 8,
 	.page_size	= 64,
@@ -828,6 +838,8 @@ static __init void davinci_evm_init(void)
 		phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK,
 						davinci_phy_fixup);
 	}
+
+	nvmem_add_lookup_table(&dm6446evm_mac_address_cell, 1);
 }
 
 MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
-- 
2.18.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related

* [PATCH 07/28] ARM: davinci: dm365-evm: use nvmem lookup for mac address
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

We now support nvmem lookups for machine code. Add a lookup for
mac-address.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 arch/arm/mach-davinci/board-dm365-evm.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index 435f7ec7d9af..cb0ac92a278e 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -28,6 +28,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/eeprom.h>
 #include <linux/v4l2-dv-timings.h>
+#include <linux/nvmem-provider.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -169,6 +170,15 @@ static struct platform_device davinci_nand_device = {
 	},
 };
 
+static struct nvmem_cell_lookup dm365evm_mac_address_cell = {
+	.info = {
+		.name = "mac-address",
+		.offset = 0x7f00,
+		.bytes = ETH_ALEN,
+	},
+	.nvmem_name = "1-00500",
+};
+
 static struct at24_platform_data eeprom_info = {
 	.byte_len       = (256*1024) / 8,
 	.page_size      = 64,
@@ -769,6 +779,8 @@ static __init void dm365_evm_init(void)
 
 	dm365_init_spi0(BIT(0), dm365_evm_spi_info,
 			ARRAY_SIZE(dm365_evm_spi_info));
+
+	nvmem_add_lookup_table(&dm365evm_mac_address_cell, 1);
 }
 
 MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM")
-- 
2.18.0

^ permalink raw reply related

* [PATCH 06/28] mtd: Add support for reading MTD devices via the nvmem API
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Alban Bedel <albeu@free.fr>

Allow drivers that use the nvmem API to read data stored on MTD devices.
For this the mtd devices are registered as read-only NVMEM providers.
On OF systems only devices that have the 'nvmem-provider' property
are registered, on non-OF system all MTD devices are registered.

Signed-off-by: Alban Bedel <albeu@free.fr>
[Bartosz:
  - use the managed variant of nvmem_register(),
  - set the nvmem name]
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/mtd/Kconfig     |  1 +
 drivers/mtd/mtdcore.c   | 50 +++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/mtd.h |  2 ++
 3 files changed, 53 insertions(+)

diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 46ab7feec6b6..f5549482d0df 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -1,5 +1,6 @@
 menuconfig MTD
 	tristate "Memory Technology Device (MTD) support"
+	imply NVMEM
 	help
 	  Memory Technology Devices are flash, RAM and similar chips, often
 	  used for solid state file systems on embedded devices. This option
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 42395df06be9..a57302eaceb5 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -488,6 +488,49 @@ int mtd_pairing_groups(struct mtd_info *mtd)
 }
 EXPORT_SYMBOL_GPL(mtd_pairing_groups);
 
+static int mtd_nvmem_reg_read(void *priv, unsigned int offset,
+			      void *val, size_t bytes)
+{
+	struct mtd_info *mtd = priv;
+	size_t retlen;
+	int err;
+
+	err = mtd_read(mtd, offset, bytes, &retlen, val);
+	if (err && err != -EUCLEAN)
+		return err;
+
+	return retlen == bytes ? 0 : -EIO;
+}
+
+static int mtd_nvmem_add(struct mtd_info *mtd)
+{
+	struct nvmem_config config = { };
+
+	config.dev = &mtd->dev;
+	config.owner = THIS_MODULE;
+	config.name = mtd->name;
+	config.reg_read = mtd_nvmem_reg_read;
+	config.size = mtd->size;
+	config.word_size = 1;
+	config.stride = 1;
+	config.read_only = true;
+	config.root_only = true;
+	config.priv = mtd;
+
+	mtd->nvmem = devm_nvmem_register(&mtd->dev, &config);
+	if (IS_ERR(mtd->nvmem)) {
+		/* Just ignore if there is no NVMEM support in the kernel */
+		if (PTR_ERR(mtd->nvmem) == -ENOSYS) {
+			mtd->nvmem = NULL;
+		} else {
+			dev_err(&mtd->dev, "Failed to register NVMEM device\n");
+			return PTR_ERR(mtd->nvmem);
+		}
+	}
+
+	return 0;
+}
+
 static struct dentry *dfs_dir_mtd;
 
 /**
@@ -570,6 +613,11 @@ int add_mtd_device(struct mtd_info *mtd)
 	if (error)
 		goto fail_added;
 
+	/* Add the nvmem provider */
+	error = mtd_nvmem_add(mtd);
+	if (error)
+		goto fail_nvmem_add;
+
 	if (!IS_ERR_OR_NULL(dfs_dir_mtd)) {
 		mtd->dbg.dfs_dir = debugfs_create_dir(dev_name(&mtd->dev), dfs_dir_mtd);
 		if (IS_ERR_OR_NULL(mtd->dbg.dfs_dir)) {
@@ -595,6 +643,8 @@ int add_mtd_device(struct mtd_info *mtd)
 	__module_get(THIS_MODULE);
 	return 0;
 
+fail_nvmem_add:
+	device_unregister(&mtd->dev);
 fail_added:
 	of_node_put(mtd_get_of_node(mtd));
 	idr_remove(&mtd_idr, i);
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index a86c4fa93115..8121c6582285 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -25,6 +25,7 @@
 #include <linux/notifier.h>
 #include <linux/device.h>
 #include <linux/of.h>
+#include <linux/nvmem-provider.h>
 
 #include <mtd/mtd-abi.h>
 
@@ -339,6 +340,7 @@ struct mtd_info {
 	struct device dev;
 	int usecount;
 	struct mtd_debug_info dbg;
+	struct nvmem_device *nvmem;
 };
 
 int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,
-- 
2.18.0

^ permalink raw reply related

* [PATCH 05/28] nvmem: remove the name field from struct nvmem_device
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

This field is never set and is only used in a single error message.
Remove the field and use nvmem_device_name() instead.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index b040370292a7..6c825ce866b6 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -26,7 +26,6 @@
 #include <linux/slab.h>
 
 struct nvmem_device {
-	const char		*name;
 	struct module		*owner;
 	struct device		dev;
 	int			stride;
@@ -712,7 +711,7 @@ static struct nvmem_device *__nvmem_device_get(struct device_node *np,
 	if (!try_module_get(nvmem->owner)) {
 		dev_err(&nvmem->dev,
 			"could not increase module refcount for cell %s\n",
-			nvmem->name);
+			nvmem_device_name(nvmem));
 
 		mutex_lock(&nvmem_mutex);
 		nvmem->users--;
-- 
2.18.0

^ permalink raw reply related

* [PATCH 04/28] nvmem: provide nvmem_device_name()
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter,
	Florian Fainelli, Ivan Khoronzhuk, Sven Van Asbroeck
  Cc: linux-doc, netdev, linux-kernel, Bartosz Golaszewski, linux-mtd,
	linux-i2c, linux-omap, linux-arm-kernel
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Kernel users don't have any means of checking the names of nvmem
devices. Add a routine that returns the name of the nvmem provider.

This will be useful for nvmem notifier subscribers - otherwise they
can't check what device is being added/removed.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c           | 6 ++++++
 include/linux/nvmem-consumer.h | 7 +++++++
 2 files changed, 13 insertions(+)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 128c8e51bff2..b040370292a7 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1440,6 +1440,12 @@ int nvmem_device_write(struct nvmem_device *nvmem,
 }
 EXPORT_SYMBOL_GPL(nvmem_device_write);
 
+const char *nvmem_device_name(struct nvmem_device *nvmem)
+{
+	return dev_name(&nvmem->dev);
+}
+EXPORT_SYMBOL_GPL(nvmem_device_name);
+
 static int __init nvmem_init(void)
 {
 	return bus_register(&nvmem_bus_type);
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index ae4d30347602..c4000a218f67 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -69,6 +69,8 @@ int nvmem_device_cell_write(struct nvmem_device *nvmem,
 
 int nvmem_register_notifier(struct notifier_block *nb);
 int nvmem_unregister_notifier(struct notifier_block *nb);
+
+const char *nvmem_device_name(struct nvmem_device *nvmem);
 #else
 
 static inline struct nvmem_cell *nvmem_cell_get(struct device *dev,
@@ -167,6 +169,11 @@ static inline int int nvmem_unregister_notifier(struct notifier_block *nb)
 {
 	return -ENOSYS;
 }
+
+static inline const char *nvmem_device_name(struct nvmem_device *nvmem)
+{
+	return ERR_PTR(-ENOSYS);
+}
 #endif /* CONFIG_NVMEM */
 
 #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
-- 
2.18.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related

* [PATCH 03/28] nvmem: add a notifier chain
From: Bartosz Golaszewski @ 2018-08-08 15:31 UTC (permalink / raw)
  To: Jonathan Corbet, Sekhar Nori, Kevin Hilman, Russell King,
	Arnd Bergmann, Greg Kroah-Hartman, David Woodhouse, Brian Norris,
	Boris Brezillon, Marek Vasut, Richard Weinberger,
	Grygorii Strashko, David S . Miller, Srinivas Kandagatla, Naren,
	Mauro Carvalho Chehab, Andrew Morton, Lukas Wunner, Dan Carpenter
  Cc: linux-doc, linux-kernel, linux-arm-kernel, linux-i2c, linux-mtd,
	linux-omap, netdev, Bartosz Golaszewski
In-Reply-To: <20180808153150.23444-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Add a blocking notifier chain with two events (add and remove) so that
users can get notified about the addition of nvmem devices they're
waiting for.

We'll use this instead of the at24 setup callback in the mityomapl138
board file.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c           | 20 ++++++++++++++++++++
 include/linux/nvmem-consumer.h | 18 ++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 329ea5b8f809..128c8e51bff2 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -65,6 +65,8 @@ static DEFINE_MUTEX(nvmem_cells_mutex);
 static LIST_HEAD(nvmem_cell_lookups);
 static DEFINE_MUTEX(nvmem_lookup_mutex);
 
+static BLOCKING_NOTIFIER_HEAD(nvmem_notifier);
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 static struct lock_class_key eeprom_lock_key;
 #endif
@@ -479,6 +481,18 @@ static int nvmem_setup_compat(struct nvmem_device *nvmem,
 	return 0;
 }
 
+int nvmem_register_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&nvmem_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(nvmem_register_notifier);
+
+int nvmem_unregister_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&nvmem_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(nvmem_unregister_notifier);
+
 /**
  * nvmem_register() - Register a nvmem device for given nvmem_config.
  * Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
@@ -559,6 +573,10 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	if (config->cells)
 		nvmem_add_cells(nvmem, config->cells, config->ncells);
 
+	rval = blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
+	if (rval)
+		goto err_device_del;
+
 	return nvmem;
 
 err_device_del:
@@ -586,6 +604,8 @@ int nvmem_unregister(struct nvmem_device *nvmem)
 	}
 	mutex_unlock(&nvmem_mutex);
 
+	blocking_notifier_call_chain(&nvmem_notifier, NVMEM_REMOVE, nvmem);
+
 	if (nvmem->flags & FLAG_COMPAT)
 		device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
 
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index f4b5d3186e94..ae4d30347602 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -14,6 +14,7 @@
 
 #include <linux/err.h>
 #include <linux/errno.h>
+#include <linux/notifier.h>
 
 struct device;
 struct device_node;
@@ -35,6 +36,11 @@ struct nvmem_cell_lookup {
 	const char		*nvmem_name;
 };
 
+enum {
+	NVMEM_ADD = 1,
+	NVMEM_REMOVE,
+};
+
 #if IS_ENABLED(CONFIG_NVMEM)
 
 /* Cell based interface */
@@ -61,6 +67,8 @@ ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem,
 int nvmem_device_cell_write(struct nvmem_device *nvmem,
 			    struct nvmem_cell_info *info, void *buf);
 
+int nvmem_register_notifier(struct notifier_block *nb);
+int nvmem_unregister_notifier(struct notifier_block *nb);
 #else
 
 static inline struct nvmem_cell *nvmem_cell_get(struct device *dev,
@@ -149,6 +157,16 @@ static inline int nvmem_device_write(struct nvmem_device *nvmem,
 {
 	return -ENOSYS;
 }
+
+static inline int nvmem_register_notifier(struct notifier_block *nb)
+{
+	return -ENOSYS;
+}
+
+static inline int int nvmem_unregister_notifier(struct notifier_block *nb)
+{
+	return -ENOSYS;
+}
 #endif /* CONFIG_NVMEM */
 
 #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
-- 
2.18.0

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox