0256b5406e
This patch removes check before freeing the memory since kfree(NULL) is safe Signed-off-by: Abdul Hussain <habdul@visteon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
480 lines
9.6 KiB
C
480 lines
9.6 KiB
C
#include <linux/module.h>
|
|
#include <linux/init.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/types.h>
|
|
#include <linux/cdev.h>
|
|
#include <asm/uaccess.h>
|
|
#include <linux/device.h>
|
|
#include <linux/spi/spi.h>
|
|
|
|
#include "linux_wlan_common.h"
|
|
|
|
#define USE_SPI_DMA 0 /* johnny add */
|
|
|
|
#ifdef WILC_ASIC_A0
|
|
#if defined(PLAT_PANDA_ES_OMAP4460)
|
|
#define MIN_SPEED 12000000
|
|
#define MAX_SPEED 24000000
|
|
#elif defined(PLAT_WMS8304)
|
|
#define MIN_SPEED 12000000
|
|
#define MAX_SPEED 24000000 /* 4000000 */
|
|
#elif defined(CUSTOMER_PLATFORM)
|
|
/*
|
|
TODO : define Clock speed under 48M.
|
|
*
|
|
* ex)
|
|
* #define MIN_SPEED 24000000
|
|
* #define MAX_SPEED 48000000
|
|
*/
|
|
#else
|
|
#define MIN_SPEED 24000000
|
|
#define MAX_SPEED 48000000
|
|
#endif
|
|
#else /* WILC_ASIC_A0 */
|
|
/* Limit clk to 6MHz on FPGA. */
|
|
#define MIN_SPEED 6000000
|
|
#define MAX_SPEED 6000000
|
|
#endif /* WILC_ASIC_A0 */
|
|
|
|
static uint32_t SPEED = MIN_SPEED;
|
|
|
|
struct spi_device *wilc_spi_dev;
|
|
void linux_spi_deinit(void *vp);
|
|
|
|
static int __init wilc_bus_probe(struct spi_device *spi)
|
|
{
|
|
|
|
PRINT_D(BUS_DBG, "spiModalias: %s\n", spi->modalias);
|
|
PRINT_D(BUS_DBG, "spiMax-Speed: %d\n", spi->max_speed_hz);
|
|
wilc_spi_dev = spi;
|
|
|
|
printk("Driver Initializing success\n");
|
|
return 0;
|
|
}
|
|
|
|
static int __exit wilc_bus_remove(struct spi_device *spi)
|
|
{
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifdef CONFIG_OF
|
|
static const struct of_device_id wilc1000_of_match[] = {
|
|
{ .compatible = "atmel,wilc_spi", },
|
|
{}
|
|
};
|
|
MODULE_DEVICE_TABLE(of, wilc1000_of_match);
|
|
#endif
|
|
|
|
struct spi_driver wilc_bus __refdata = {
|
|
.driver = {
|
|
.name = MODALIAS,
|
|
#ifdef CONFIG_OF
|
|
.of_match_table = wilc1000_of_match,
|
|
#endif
|
|
},
|
|
.probe = wilc_bus_probe,
|
|
.remove = __exit_p(wilc_bus_remove),
|
|
};
|
|
|
|
|
|
void linux_spi_deinit(void *vp)
|
|
{
|
|
|
|
spi_unregister_driver(&wilc_bus);
|
|
|
|
SPEED = MIN_SPEED;
|
|
PRINT_ER("@@@@@@@@@@@@ restore SPI speed to %d @@@@@@@@@\n", SPEED);
|
|
|
|
}
|
|
|
|
|
|
|
|
int linux_spi_init(void *vp)
|
|
{
|
|
int ret = 1;
|
|
static int called;
|
|
|
|
|
|
if (called == 0) {
|
|
called++;
|
|
ret = spi_register_driver(&wilc_bus);
|
|
}
|
|
|
|
/* change return value to match WILC interface */
|
|
(ret < 0) ? (ret = 0) : (ret = 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
#if defined(PLAT_WMS8304)
|
|
#define TXRX_PHASE_SIZE (4096)
|
|
#endif
|
|
|
|
#if defined (NM73131_0_BOARD)
|
|
|
|
int linux_spi_write(uint8_t *b, uint32_t len)
|
|
{
|
|
|
|
int ret;
|
|
|
|
if (len > 0 && b != NULL) {
|
|
struct spi_message msg;
|
|
PRINT_D(BUS_DBG, "Request writing %d bytes\n", len);
|
|
struct spi_transfer tr = {
|
|
.tx_buf = b,
|
|
.len = len,
|
|
.speed_hz = SPEED,
|
|
.delay_usecs = 0,
|
|
};
|
|
|
|
spi_message_init(&msg);
|
|
spi_message_add_tail(&tr, &msg);
|
|
ret = spi_sync(wilc_spi_dev, &msg);
|
|
if (ret < 0) {
|
|
PRINT_ER("SPI transaction failed\n");
|
|
}
|
|
|
|
} else {
|
|
PRINT_ER("can't write data with the following length: %d\n", len);
|
|
PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len);
|
|
ret = -1;
|
|
}
|
|
|
|
/* change return value to match WILC interface */
|
|
(ret < 0) ? (ret = 0) : (ret = 1);
|
|
|
|
|
|
return ret;
|
|
}
|
|
|
|
#elif defined(TXRX_PHASE_SIZE)
|
|
|
|
int linux_spi_write(uint8_t *b, uint32_t len)
|
|
{
|
|
int ret;
|
|
if (len > 0 && b != NULL) {
|
|
int i = 0;
|
|
int blk = len / TXRX_PHASE_SIZE;
|
|
int remainder = len % TXRX_PHASE_SIZE;
|
|
|
|
char *r_buffer = kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL);
|
|
if (!r_buffer) {
|
|
PRINT_ER("Failed to allocate memory for r_buffer\n");
|
|
}
|
|
|
|
if (blk) {
|
|
while (i < blk) {
|
|
struct spi_message msg;
|
|
struct spi_transfer tr = {
|
|
.tx_buf = b + (i * TXRX_PHASE_SIZE),
|
|
.len = TXRX_PHASE_SIZE,
|
|
.speed_hz = SPEED,
|
|
.bits_per_word = 8,
|
|
.delay_usecs = 0,
|
|
};
|
|
|
|
tr.rx_buf = r_buffer;
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
spi_message_init(&msg);
|
|
msg.spi = wilc_spi_dev;
|
|
msg.is_dma_mapped = USE_SPI_DMA;
|
|
|
|
spi_message_add_tail(&tr, &msg);
|
|
ret = spi_sync(wilc_spi_dev, &msg);
|
|
if (ret < 0) {
|
|
PRINT_ER("SPI transaction failed\n");
|
|
}
|
|
i++;
|
|
|
|
}
|
|
}
|
|
if (remainder) {
|
|
struct spi_message msg;
|
|
struct spi_transfer tr = {
|
|
.tx_buf = b + (blk * TXRX_PHASE_SIZE),
|
|
.len = remainder,
|
|
.speed_hz = SPEED,
|
|
.bits_per_word = 8,
|
|
.delay_usecs = 0,
|
|
};
|
|
tr.rx_buf = r_buffer;
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
spi_message_init(&msg);
|
|
msg.spi = wilc_spi_dev;
|
|
msg.is_dma_mapped = USE_SPI_DMA; /* rachel */
|
|
|
|
spi_message_add_tail(&tr, &msg);
|
|
ret = spi_sync(wilc_spi_dev, &msg);
|
|
if (ret < 0) {
|
|
PRINT_ER("SPI transaction failed\n");
|
|
}
|
|
}
|
|
kfree(r_buffer);
|
|
} else {
|
|
PRINT_ER("can't write data with the following length: %d\n", len);
|
|
PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len);
|
|
ret = -1;
|
|
}
|
|
|
|
/* change return value to match WILC interface */
|
|
(ret < 0) ? (ret = 0) : (ret = 1);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#else
|
|
int linux_spi_write(uint8_t *b, uint32_t len)
|
|
{
|
|
|
|
int ret;
|
|
struct spi_message msg;
|
|
|
|
if (len > 0 && b != NULL) {
|
|
struct spi_transfer tr = {
|
|
.tx_buf = b,
|
|
.len = len,
|
|
.speed_hz = SPEED,
|
|
.delay_usecs = 0,
|
|
};
|
|
char *r_buffer = kzalloc(len, GFP_KERNEL);
|
|
if (!r_buffer) {
|
|
PRINT_ER("Failed to allocate memory for r_buffer\n");
|
|
}
|
|
tr.rx_buf = r_buffer;
|
|
PRINT_D(BUS_DBG, "Request writing %d bytes\n", len);
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
spi_message_init(&msg);
|
|
/* [[johnny add */
|
|
msg.spi = wilc_spi_dev;
|
|
msg.is_dma_mapped = USE_SPI_DMA;
|
|
/* ]] */
|
|
spi_message_add_tail(&tr, &msg);
|
|
|
|
ret = spi_sync(wilc_spi_dev, &msg);
|
|
if (ret < 0) {
|
|
PRINT_ER("SPI transaction failed\n");
|
|
}
|
|
|
|
kfree(r_buffer);
|
|
} else {
|
|
PRINT_ER("can't write data with the following length: %d\n", len);
|
|
PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n", len);
|
|
ret = -1;
|
|
}
|
|
|
|
/* change return value to match WILC interface */
|
|
(ret < 0) ? (ret = 0) : (ret = 1);
|
|
|
|
|
|
return ret;
|
|
}
|
|
|
|
#endif
|
|
|
|
#if defined (NM73131_0_BOARD)
|
|
|
|
int linux_spi_read(unsigned char *rb, unsigned long rlen)
|
|
{
|
|
|
|
int ret;
|
|
|
|
if (rlen > 0) {
|
|
struct spi_message msg;
|
|
struct spi_transfer tr = {
|
|
.rx_buf = rb,
|
|
.len = rlen,
|
|
.speed_hz = SPEED,
|
|
.delay_usecs = 0,
|
|
|
|
};
|
|
|
|
spi_message_init(&msg);
|
|
spi_message_add_tail(&tr, &msg);
|
|
ret = spi_sync(wilc_spi_dev, &msg);
|
|
if (ret < 0) {
|
|
PRINT_ER("SPI transaction failed\n");
|
|
}
|
|
} else {
|
|
PRINT_ER("can't read data with the following length: %ld\n", rlen);
|
|
ret = -1;
|
|
}
|
|
/* change return value to match WILC interface */
|
|
(ret < 0) ? (ret = 0) : (ret = 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
#elif defined(TXRX_PHASE_SIZE)
|
|
|
|
int linux_spi_read(unsigned char *rb, unsigned long rlen)
|
|
{
|
|
int ret;
|
|
|
|
if (rlen > 0) {
|
|
int i = 0;
|
|
|
|
int blk = rlen / TXRX_PHASE_SIZE;
|
|
int remainder = rlen % TXRX_PHASE_SIZE;
|
|
|
|
char *t_buffer = kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL);
|
|
if (!t_buffer) {
|
|
PRINT_ER("Failed to allocate memory for t_buffer\n");
|
|
}
|
|
|
|
if (blk) {
|
|
while (i < blk) {
|
|
struct spi_message msg;
|
|
struct spi_transfer tr = {
|
|
.rx_buf = rb + (i * TXRX_PHASE_SIZE),
|
|
.len = TXRX_PHASE_SIZE,
|
|
.speed_hz = SPEED,
|
|
.bits_per_word = 8,
|
|
.delay_usecs = 0,
|
|
};
|
|
tr.tx_buf = t_buffer;
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
spi_message_init(&msg);
|
|
msg.spi = wilc_spi_dev;
|
|
msg.is_dma_mapped = USE_SPI_DMA;
|
|
|
|
spi_message_add_tail(&tr, &msg);
|
|
ret = spi_sync(wilc_spi_dev, &msg);
|
|
if (ret < 0) {
|
|
PRINT_ER("SPI transaction failed\n");
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
if (remainder) {
|
|
struct spi_message msg;
|
|
struct spi_transfer tr = {
|
|
.rx_buf = rb + (blk * TXRX_PHASE_SIZE),
|
|
.len = remainder,
|
|
.speed_hz = SPEED,
|
|
.bits_per_word = 8,
|
|
.delay_usecs = 0,
|
|
};
|
|
tr.tx_buf = t_buffer;
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
spi_message_init(&msg);
|
|
msg.spi = wilc_spi_dev;
|
|
msg.is_dma_mapped = USE_SPI_DMA; /* rachel */
|
|
|
|
spi_message_add_tail(&tr, &msg);
|
|
ret = spi_sync(wilc_spi_dev, &msg);
|
|
if (ret < 0) {
|
|
PRINT_ER("SPI transaction failed\n");
|
|
}
|
|
}
|
|
|
|
kfree(t_buffer);
|
|
} else {
|
|
PRINT_ER("can't read data with the following length: %ld\n", rlen);
|
|
ret = -1;
|
|
}
|
|
/* change return value to match WILC interface */
|
|
(ret < 0) ? (ret = 0) : (ret = 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
#else
|
|
int linux_spi_read(unsigned char *rb, unsigned long rlen)
|
|
{
|
|
|
|
int ret;
|
|
|
|
if (rlen > 0) {
|
|
struct spi_message msg;
|
|
struct spi_transfer tr = {
|
|
.rx_buf = rb,
|
|
.len = rlen,
|
|
.speed_hz = SPEED,
|
|
.delay_usecs = 0,
|
|
|
|
};
|
|
char *t_buffer = kzalloc(rlen, GFP_KERNEL);
|
|
if (!t_buffer) {
|
|
PRINT_ER("Failed to allocate memory for t_buffer\n");
|
|
}
|
|
tr.tx_buf = t_buffer;
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
spi_message_init(&msg);
|
|
/* [[ johnny add */
|
|
msg.spi = wilc_spi_dev;
|
|
msg.is_dma_mapped = USE_SPI_DMA;
|
|
/* ]] */
|
|
spi_message_add_tail(&tr, &msg);
|
|
|
|
ret = spi_sync(wilc_spi_dev, &msg);
|
|
if (ret < 0) {
|
|
PRINT_ER("SPI transaction failed\n");
|
|
}
|
|
kfree(t_buffer);
|
|
} else {
|
|
PRINT_ER("can't read data with the following length: %ld\n", rlen);
|
|
ret = -1;
|
|
}
|
|
/* change return value to match WILC interface */
|
|
(ret < 0) ? (ret = 0) : (ret = 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
#endif
|
|
|
|
int linux_spi_write_read(unsigned char *wb, unsigned char *rb, unsigned int rlen)
|
|
{
|
|
|
|
int ret;
|
|
|
|
if (rlen > 0) {
|
|
struct spi_message msg;
|
|
struct spi_transfer tr = {
|
|
.rx_buf = rb,
|
|
.tx_buf = wb,
|
|
.len = rlen,
|
|
.speed_hz = SPEED,
|
|
.bits_per_word = 8,
|
|
.delay_usecs = 0,
|
|
|
|
};
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
spi_message_init(&msg);
|
|
msg.spi = wilc_spi_dev;
|
|
msg.is_dma_mapped = USE_SPI_DMA;
|
|
|
|
spi_message_add_tail(&tr, &msg);
|
|
ret = spi_sync(wilc_spi_dev, &msg);
|
|
if (ret < 0) {
|
|
PRINT_ER("SPI transaction failed\n");
|
|
}
|
|
} else {
|
|
PRINT_ER("can't read data with the following length: %d\n", rlen);
|
|
ret = -1;
|
|
}
|
|
/* change return value to match WILC interface */
|
|
(ret < 0) ? (ret = 0) : (ret = 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int linux_spi_set_max_speed(void)
|
|
{
|
|
SPEED = MAX_SPEED;
|
|
|
|
PRINT_INFO(BUS_DBG, "@@@@@@@@@@@@ change SPI speed to %d @@@@@@@@@\n", SPEED);
|
|
return 1;
|
|
}
|