Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fjes: Hardware cleanup routine

This patch adds hardware cleanup routine to be
invoked at driver's .remove routine.

Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Taku Izumi and committed by
David S. Miller
a18aaec2 8cdc3f6c

+67
+66
drivers/net/fjes/fjes_hw.c
··· 56 56 return base; 57 57 } 58 58 59 + static void fjes_hw_iounmap(struct fjes_hw *hw) 60 + { 61 + iounmap(hw->base); 62 + release_mem_region(hw->hw_res.start, hw->hw_res.size); 63 + } 64 + 59 65 int fjes_hw_reset(struct fjes_hw *hw) 60 66 { 61 67 union REG_DCTL dctl; ··· 115 109 return 0; 116 110 } 117 111 112 + static void fjes_hw_free_shared_status_region(struct fjes_hw *hw) 113 + { 114 + kfree(hw->hw_info.share); 115 + hw->hw_info.share = NULL; 116 + } 117 + 118 118 static int fjes_hw_alloc_epbuf(struct epbuf_handler *epbh) 119 119 { 120 120 void *mem; ··· 136 124 epbh->ring = (u8 *)(mem + sizeof(union ep_buffer_info)); 137 125 138 126 return 0; 127 + } 128 + 129 + static void fjes_hw_free_epbuf(struct epbuf_handler *epbh) 130 + { 131 + if (epbh->buffer) 132 + vfree(epbh->buffer); 133 + 134 + epbh->buffer = NULL; 135 + epbh->size = 0; 136 + 137 + epbh->info = NULL; 138 + epbh->ring = NULL; 139 139 } 140 140 141 141 void fjes_hw_setup_epbuf(struct epbuf_handler *epbh, u8 *mac_addr, u32 mtu) ··· 282 258 return 0; 283 259 } 284 260 261 + static void fjes_hw_cleanup(struct fjes_hw *hw) 262 + { 263 + int epidx; 264 + 265 + if (!hw->ep_shm_info) 266 + return; 267 + 268 + fjes_hw_free_shared_status_region(hw); 269 + 270 + kfree(hw->hw_info.req_buf); 271 + hw->hw_info.req_buf = NULL; 272 + 273 + kfree(hw->hw_info.res_buf); 274 + hw->hw_info.res_buf = NULL; 275 + 276 + for (epidx = 0; epidx < hw->max_epid ; epidx++) { 277 + if (epidx == hw->my_epid) 278 + continue; 279 + fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].tx); 280 + fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].rx); 281 + } 282 + 283 + kfree(hw->ep_shm_info); 284 + hw->ep_shm_info = NULL; 285 + } 286 + 285 287 int fjes_hw_init(struct fjes_hw *hw) 286 288 { 287 289 int ret; ··· 333 283 ret = fjes_hw_setup(hw); 334 284 335 285 return ret; 286 + } 287 + 288 + void fjes_hw_exit(struct fjes_hw *hw) 289 + { 290 + int ret; 291 + 292 + if (hw->base) { 293 + ret = fjes_hw_reset(hw); 294 + if (ret) 295 + pr_err("%s: reset error", __func__); 296 + 297 + fjes_hw_iounmap(hw); 298 + hw->base = NULL; 299 + } 300 + 301 + fjes_hw_cleanup(hw); 336 302 } 337 303 338 304 void fjes_hw_set_irqmask(struct fjes_hw *hw,
+1
drivers/net/fjes/fjes_hw.h
··· 241 241 }; 242 242 243 243 int fjes_hw_init(struct fjes_hw *); 244 + void fjes_hw_exit(struct fjes_hw *); 244 245 int fjes_hw_reset(struct fjes_hw *); 245 246 246 247 void fjes_hw_init_command_registers(struct fjes_hw *,