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
8 #define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
10 #include <linux/version.h>
11 #include <linux/init.h>
12 #include <linux/module.h>
13 #include <linux/netdevice.h>
14 #include <mach/mbox-db5500.h>
15 #include <net/caif/caif_shm.h>
17 MODULE_LICENSE("GPL");
18 MODULE_DESCRIPTION("CAIF Shared Memory protocol driver");
20 #define MAX_SHM_INSTANCES 1
28 static struct shmdev_layer shmdev_lyr
[MAX_SHM_INSTANCES
];
30 static unsigned int shm_start
;
31 static unsigned int shm_size
;
33 module_param(shm_size
, uint
, 0440);
34 MODULE_PARM_DESC(shm_total_size
, "Start of SHM shared memory");
36 module_param(shm_start
, uint
, 0440);
37 MODULE_PARM_DESC(shm_total_start
, "Total Size of SHM shared memory");
39 static int shmdev_send_msg(u32 dev_id
, u32 mbx_msg
)
41 /* Always block until msg is written successfully */
42 mbox_send(shmdev_lyr
[dev_id
].hmbx
, mbx_msg
, true);
46 static int shmdev_mbx_setup(void *pshmdrv_cb
, struct shmdev_layer
*pshm_dev
,
50 * For UX5500, we have only 1 SHM instance which uses MBX0
51 * for communication with the peer modem
53 pshm_dev
->hmbx
= mbox_setup(MBX_ACC0
, pshmdrv_cb
, pshm_drv
);
61 static int __init
caif_shmdev_init(void)
65 /* Loop is currently overkill, there is only one instance */
66 for (i
= 0; i
< MAX_SHM_INSTANCES
; i
++) {
68 shmdev_lyr
[i
].shm_base_addr
= shm_start
;
69 shmdev_lyr
[i
].shm_total_sz
= shm_size
;
71 if (((char *)shmdev_lyr
[i
].shm_base_addr
== NULL
)
72 || (shmdev_lyr
[i
].shm_total_sz
<= 0)) {
74 "Shared memory Address and/or Size incorrect"
75 ", Bailing out ...\n");
80 pr_info("SHM AREA (instance %d) STARTS"
81 " AT %p\n", i
, (char *)shmdev_lyr
[i
].shm_base_addr
);
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
;
88 * Finally, CAIF core module is called with details in place:
93 result
= caif_shmcore_probe(&shmdev_lyr
[i
]);
96 "Could not probe SHM core (instance %d)"
97 " Bailing out ...\n", result
, i
);
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.
110 for (i
= 0; i
< MAX_SHM_INSTANCES
; i
++) {
111 if (shmdev_lyr
[i
].pshm_netdev
)
112 unregister_netdev(shmdev_lyr
[i
].pshm_netdev
);
117 static void __exit
caif_shmdev_exit(void)
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
);
128 module_init(caif_shmdev_init
);
129 module_exit(caif_shmdev_exit
);