/* * Atheros AR71XX/AR724X/AR913X Calibration data in NAND flash fixup * * Copyright (c) 2012 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. */ #include #include #include #include "dev-ap9x-pci.h" #include "dev-wmac.h" #include "dev-eth.h" #include "nand-caldata-fixup.h" static struct ath79_caldata_fixup *ath79_caldata; static void mtd_caldata_add(struct mtd_info *mtd) { int i, ret; size_t retlen; struct ath9k_platform_data *wmac_pdata; struct ag71xx_platform_data *eth_pdata; /* If the device added doesn't match the name of the device containing * caldata, then we do nothing; just return */ if (strcmp(mtd->name, ath79_caldata->name)) return; /* If the caldata PCIe address provided by the platform is non-null, * then fetch the data from MTD and fill it into the platform * structure */ for (i = 0; i < sizeof(ath79_caldata->pcie_caldata_addr) / sizeof(loff_t); i++) { if (ath79_caldata->pcie_caldata_addr[i] == FIXUP_UNDEFINED) continue; wmac_pdata = ap9x_pci_get_wmac_data(i); ret = mtd_read(mtd, ath79_caldata->pcie_caldata_addr[i], sizeof(wmac_pdata->eeprom_data), &retlen, (u_char *) wmac_pdata->eeprom_data); if (retlen != sizeof(wmac_pdata->eeprom_data) || ret < 0) { pr_err("%s: Error while reading %dB at offset 0x%08x\n", mtd->name, sizeof(wmac_pdata->eeprom_data), (u_int) ath79_caldata->pcie_caldata_addr[i]); } } /* Same here for WMAC caldata */ if (ath79_caldata->wmac_caldata_addr != FIXUP_UNDEFINED) { wmac_pdata = ath79_get_wmac_data(); ret = mtd_read(mtd, ath79_caldata->wmac_caldata_addr, sizeof(wmac_pdata->eeprom_data), &retlen, (u_char *) wmac_pdata->eeprom_data); if (retlen != sizeof(wmac_pdata->eeprom_data) || ret < 0) { pr_err("%s: Error while reading %dB at offset 0x%08x\n", mtd->name, sizeof(wmac_pdata->eeprom_data), (u_int) ath79_caldata->wmac_caldata_addr); } } /* Same here for Ethernet MAC@ */ for (i = 0; i < sizeof(ath79_caldata->mac_addr) / sizeof(loff_t); i++) { switch (i) { case 0: eth_pdata = &ath79_eth0_data; break; case 1: eth_pdata = &ath79_eth1_data; break; default: eth_pdata = NULL; } if (ath79_caldata->mac_addr[i] == FIXUP_UNDEFINED) continue; ret = mtd_read(mtd, ath79_caldata->mac_addr[i], sizeof(eth_pdata->mac_addr), &retlen, (u_char *) eth_pdata->mac_addr); if (retlen != sizeof(eth_pdata->mac_addr) || ret < 0) { pr_err("%s: Error while reading %dB at offset 0x%08x\n", mtd->name, sizeof(eth_pdata->mac_addr), (u_int) ath79_caldata->mac_addr[i]); } } } static void mtd_caldata_remove(struct mtd_info *mtd) { return; } static void add_mtd_caldata_notifier(void) { static struct mtd_notifier not = { .add = mtd_caldata_add, .remove = mtd_caldata_remove, }; register_mtd_user(¬); } void __init ath79_mtd_caldata_fixup(struct ath79_caldata_fixup *platform_caldata) { ath79_caldata = platform_caldata; add_mtd_caldata_notifier(); }