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

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.37-rc5 129 lines 3.2 kB view raw
1/* 2 * Copyright (C) ST-Ericsson AB 2010 3 * Contact: Sjur Brendeland / sjur.brandeland@stericsson.com 4 * Author: Amarnath Revanna / amarnath.bangalore.revanna@stericsson.com 5 * License terms: GNU General Public License (GPL) version 2 6 */ 7 8#define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt 9 10#include <linux/version.h> 11#include <linux/init.h> 12#include <linux/module.h> 13#include <linux/netdevice.h> 14#include <mach/mbox.h> 15#include <net/caif/caif_shm.h> 16 17MODULE_LICENSE("GPL"); 18MODULE_DESCRIPTION("CAIF Shared Memory protocol driver"); 19 20#define MAX_SHM_INSTANCES 1 21 22enum { 23 MBX_ACC0, 24 MBX_ACC1, 25 MBX_DSP 26}; 27 28static struct shmdev_layer shmdev_lyr[MAX_SHM_INSTANCES]; 29 30static unsigned int shm_start; 31static unsigned int shm_size; 32 33module_param(shm_size, uint , 0440); 34MODULE_PARM_DESC(shm_total_size, "Start of SHM shared memory"); 35 36module_param(shm_start, uint , 0440); 37MODULE_PARM_DESC(shm_total_start, "Total Size of SHM shared memory"); 38 39static int shmdev_send_msg(u32 dev_id, u32 mbx_msg) 40{ 41 /* Always block until msg is written successfully */ 42 mbox_send(shmdev_lyr[dev_id].hmbx, mbx_msg, true); 43 return 0; 44} 45 46static int shmdev_mbx_setup(void *pshmdrv_cb, struct shmdev_layer *pshm_dev, 47 void *pshm_drv) 48{ 49 /* 50 * For UX5500, we have only 1 SHM instance which uses MBX0 51 * for communication with the peer modem 52 */ 53 pshm_dev->hmbx = mbox_setup(MBX_ACC0, pshmdrv_cb, pshm_drv); 54 55 if (!pshm_dev->hmbx) 56 return -ENODEV; 57 else 58 return 0; 59} 60 61static int __init caif_shmdev_init(void) 62{ 63 int i, result; 64 65 /* Loop is currently overkill, there is only one instance */ 66 for (i = 0; i < MAX_SHM_INSTANCES; i++) { 67 68 shmdev_lyr[i].shm_base_addr = shm_start; 69 shmdev_lyr[i].shm_total_sz = shm_size; 70 71 if (((char *)shmdev_lyr[i].shm_base_addr == NULL) 72 || (shmdev_lyr[i].shm_total_sz <= 0)) { 73 pr_warn("ERROR," 74 "Shared memory Address and/or Size incorrect" 75 ", Bailing out ...\n"); 76 result = -EINVAL; 77 goto clean; 78 } 79 80 pr_info("SHM AREA (instance %d) STARTS" 81 " AT %p\n", i, (char *)shmdev_lyr[i].shm_base_addr); 82 83 shmdev_lyr[i].shm_id = i; 84 shmdev_lyr[i].pshmdev_mbxsend = shmdev_send_msg; 85 shmdev_lyr[i].pshmdev_mbxsetup = shmdev_mbx_setup; 86 87 /* 88 * Finally, CAIF core module is called with details in place: 89 * 1. SHM base address 90 * 2. SHM size 91 * 3. MBX handle 92 */ 93 result = caif_shmcore_probe(&shmdev_lyr[i]); 94 if (result) { 95 pr_warn("ERROR[%d]," 96 "Could not probe SHM core (instance %d)" 97 " Bailing out ...\n", result, i); 98 goto clean; 99 } 100 } 101 102 return 0; 103 104clean: 105 /* 106 * For now, we assume that even if one instance of SHM fails, we bail 107 * out of the driver support completely. For this, we need to release 108 * any memory allocated and unregister any instance of SHM net device. 109 */ 110 for (i = 0; i < MAX_SHM_INSTANCES; i++) { 111 if (shmdev_lyr[i].pshm_netdev) 112 unregister_netdev(shmdev_lyr[i].pshm_netdev); 113 } 114 return result; 115} 116 117static void __exit caif_shmdev_exit(void) 118{ 119 int i; 120 121 for (i = 0; i < MAX_SHM_INSTANCES; i++) { 122 caif_shmcore_remove(shmdev_lyr[i].pshm_netdev); 123 kfree((void *)shmdev_lyr[i].shm_base_addr); 124 } 125 126} 127 128module_init(caif_shmdev_init); 129module_exit(caif_shmdev_exit);