Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a1f55391 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mpq8092: Support to fetch Ethernet MAC address"

parents 235cd46b 709f41b1
Loading
Loading
Loading
Loading
+72 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
@@ -44,6 +45,11 @@
#include "spm.h"
#include "pm.h"

#define MPQ8092_MAC_FUSE_PHYS     0xfc4bc0e0
#define MPQ8092_MAC_FUSE_SIZE     0x10

static const char mac_addr_prop_name[] = "mac-address";

static void __init mpq8092_early_memory(void)
{
	of_scan_flat_dt(dt_scan_for_memory_hole, NULL);
@@ -68,6 +74,70 @@ static struct of_dev_auxdata mpq8092_auxdata_lookup[] __initdata = {
	{}
};

static int emac_dt_update(int cell, phys_addr_t addr, unsigned long size)
{
	static int offset[ETH_ALEN] = { 5, 4, 3, 2, 1, 0};
	void __iomem *fuse_reg;
	struct device_node *np = NULL;
	struct property *pmac = NULL;
	struct property *pp = NULL;
	u8 buf[ETH_ALEN];
	int n, retval = 0;

	fuse_reg = ioremap(addr, size);
	if (!fuse_reg) {
		pr_err("failed to ioremap efuse to read mac address");
		return -ENOMEM;
	}

	for (n = 0; n < ETH_ALEN; n++)
		buf[n] = ioread8(fuse_reg + offset[n]);

	iounmap(fuse_reg);

	if (!is_valid_ether_addr(buf)) {
		pr_err("invalid MAC address in efuse\n");
		return -ENODATA;
	}

	pmac = kzalloc(sizeof(*pmac) + ETH_ALEN, GFP_KERNEL);
	if (!pmac) {
		pr_err("failed to alloc memory for mac address\n");
		return -ENOMEM;
	}

	pmac->value = pmac + 1;
	pmac->length = ETH_ALEN;
	pmac->name = (char *)mac_addr_prop_name;
	memcpy(pmac->value, buf, ETH_ALEN);

	for_each_compatible_node(np, NULL, "qcom,emac") {
		if (of_property_read_u32(np, "cell-index", &n))
			continue;

		if (n == cell)
			break;
	}

	if (!np) {
		pr_err("failed to find dt node for emac%d", cell);
		retval = -ENODEV;
		goto out;
	}

	pp = of_find_property(np, pmac->name, NULL);
	if (pp)
		of_update_property(np, pmac);
	else
		of_add_property(np, pmac);

out:
	if (retval && pmac)
		kfree(pmac);

	return retval;
}

/*
 * Used to satisfy dependencies for devices that need to be
 * run early or in a particular order. Most likely your device doesn't fall
@@ -89,6 +159,8 @@ void __init mpq8092_add_drivers(void)
		msm_clock_init(&mpq8092_clock_init_data);
	tsens_tm_init_driver();
	msm_thermal_device_init();

	emac_dt_update(0, MPQ8092_MAC_FUSE_PHYS, MPQ8092_MAC_FUSE_SIZE);
}