Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Driver for Solarflare network controllers and boards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright 2005-2006 Fen Systems Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright 2006-2013 Solarflare Communications Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/mtd/mtd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "net_driver.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "efx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define to_efx_mtd_partition(mtd)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	container_of(mtd, struct efx_mtd_partition, mtd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) /* MTD interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	struct efx_nic *efx = mtd->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	return efx->type->mtd_erase(mtd, erase->addr, erase->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) static void efx_mtd_sync(struct mtd_info *mtd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	struct efx_nic *efx = mtd->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	rc = efx->type->mtd_sync(mtd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		pr_err("%s: %s sync failed (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		       part->name, part->dev_type_name, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static void efx_mtd_remove_partition(struct efx_mtd_partition *part)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		rc = mtd_device_unregister(&part->mtd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		if (rc != -EBUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		ssleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	WARN_ON(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	list_del(&part->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) int efx_mtd_add(struct efx_nic *efx, struct efx_mtd_partition *parts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		size_t n_parts, size_t sizeof_part)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	struct efx_mtd_partition *part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	for (i = 0; i < n_parts; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		part = (struct efx_mtd_partition *)((char *)parts +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 						    i * sizeof_part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		part->mtd.writesize = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		if (!(part->mtd.flags & MTD_NO_ERASE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 			part->mtd.flags |= MTD_WRITEABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		part->mtd.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		part->mtd.priv = efx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		part->mtd.name = part->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		part->mtd._erase = efx_mtd_erase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		part->mtd._read = efx->type->mtd_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		part->mtd._write = efx->type->mtd_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		part->mtd._sync = efx_mtd_sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		efx->type->mtd_rename(part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		if (mtd_device_register(&part->mtd, NULL, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		/* Add to list in order - efx_mtd_remove() depends on this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		list_add_tail(&part->node, &efx->mtd_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	while (i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		part = (struct efx_mtd_partition *)((char *)parts +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 						    i * sizeof_part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		efx_mtd_remove_partition(part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	/* Failure is unlikely here, but probably means we're out of memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) void efx_mtd_remove(struct efx_nic *efx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	struct efx_mtd_partition *parts, *part, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	WARN_ON(efx_dev_registered(efx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	if (list_empty(&efx->mtd_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	parts = list_first_entry(&efx->mtd_list, struct efx_mtd_partition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 				 node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	list_for_each_entry_safe(part, next, &efx->mtd_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		efx_mtd_remove_partition(part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	kfree(parts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) void efx_mtd_rename(struct efx_nic *efx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	struct efx_mtd_partition *part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	ASSERT_RTNL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	list_for_each_entry(part, &efx->mtd_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		efx->type->mtd_rename(part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }