1bb17230cSRafał Miłecki // SPDX-License-Identifier: GPL-2.0 2bb17230cSRafał Miłecki /* 3bb17230cSRafał Miłecki * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl> 4bb17230cSRafał Miłecki */ 5bb17230cSRafał Miłecki 6bb17230cSRafał Miłecki #include <linux/module.h> 7bb17230cSRafał Miłecki #include <linux/init.h> 8bb17230cSRafał Miłecki #include <linux/of.h> 9bb17230cSRafał Miłecki #include <linux/mtd/mtd.h> 10bb17230cSRafał Miłecki #include <linux/slab.h> 11bb17230cSRafał Miłecki #include <linux/mtd/partitions.h> 12bb17230cSRafał Miłecki 13bb17230cSRafał Miłecki #include "ofpart_bcm4908.h" 14bb17230cSRafał Miłecki 15bb17230cSRafał Miłecki #define BLPARAMS_FW_OFFSET "NAND_RFS_OFS" 16bb17230cSRafał Miłecki 17bb17230cSRafał Miłecki static long long bcm4908_partitions_fw_offset(void) 18bb17230cSRafał Miłecki { 19bb17230cSRafał Miłecki struct device_node *root; 20bb17230cSRafał Miłecki struct property *prop; 21bb17230cSRafał Miłecki const char *s; 22bb17230cSRafał Miłecki 23bb17230cSRafał Miłecki root = of_find_node_by_path("/"); 24bb17230cSRafał Miłecki if (!root) 25bb17230cSRafał Miłecki return -ENOENT; 26bb17230cSRafał Miłecki 27bb17230cSRafał Miłecki of_property_for_each_string(root, "brcm_blparms", prop, s) { 28bb17230cSRafał Miłecki size_t len = strlen(BLPARAMS_FW_OFFSET); 29bb17230cSRafał Miłecki unsigned long offset; 30bb17230cSRafał Miłecki int err; 31bb17230cSRafał Miłecki 32bb17230cSRafał Miłecki if (strncmp(s, BLPARAMS_FW_OFFSET, len) || s[len] != '=') 33bb17230cSRafał Miłecki continue; 34bb17230cSRafał Miłecki 35bb17230cSRafał Miłecki err = kstrtoul(s + len + 1, 0, &offset); 36bb17230cSRafał Miłecki if (err) { 37bb17230cSRafał Miłecki pr_err("failed to parse %s\n", s + len + 1); 38*e607879bSMiaoqian Lin of_node_put(root); 39bb17230cSRafał Miłecki return err; 40bb17230cSRafał Miłecki } 41bb17230cSRafał Miłecki 42*e607879bSMiaoqian Lin of_node_put(root); 43bb17230cSRafał Miłecki return offset << 10; 44bb17230cSRafał Miłecki } 45bb17230cSRafał Miłecki 46*e607879bSMiaoqian Lin of_node_put(root); 47bb17230cSRafał Miłecki return -ENOENT; 48bb17230cSRafał Miłecki } 49bb17230cSRafał Miłecki 50bb17230cSRafał Miłecki int bcm4908_partitions_post_parse(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts) 51bb17230cSRafał Miłecki { 52bb17230cSRafał Miłecki long long fw_offset; 53bb17230cSRafał Miłecki int i; 54bb17230cSRafał Miłecki 55bb17230cSRafał Miłecki fw_offset = bcm4908_partitions_fw_offset(); 56bb17230cSRafał Miłecki 57bb17230cSRafał Miłecki for (i = 0; i < nr_parts; i++) { 58bb17230cSRafał Miłecki if (of_device_is_compatible(parts[i].of_node, "brcm,bcm4908-firmware")) { 59bb17230cSRafał Miłecki if (fw_offset < 0 || parts[i].offset == fw_offset) 60bb17230cSRafał Miłecki parts[i].name = "firmware"; 61bb17230cSRafał Miłecki else 62bb17230cSRafał Miłecki parts[i].name = "backup"; 63bb17230cSRafał Miłecki } 64bb17230cSRafał Miłecki } 65bb17230cSRafał Miłecki 66bb17230cSRafał Miłecki return 0; 67bb17230cSRafał Miłecki } 68