mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
spi_fpga_init: fix slab corruption bug
fix this bug: [ 74.920000] bt turn on power bcm4329 patch_plus -d /etc/bluez/bcm4325/BCM4329B1_TestOnly_0237_26MHz_SEMCO_B23.hcd /dev/ttySPI0 bcm4325 1500000 speed of uart to :1500000 [ 75.330000] uart->index=0 [ 75.330000] baud=115200,quot=0x34 [ 75.340000] baud=115200,quot=0x34 [ 75.340000] Slab corruption: size-32 start=cc3b3660, len=32 [ 75.340000] 010: 6b 6b 6b 6b b4 36 3b cc 6b 6b 6b 6b 6b 6b 6b a5 [ 75.370000] Prev obj: start=cc3b3640, len=32 [ 75.370000] 000: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b [ 75.370000] 010: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5 [ 75.370000] Next obj: start=cc3b3680, len=32 [ 75.370000] 000: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b [ 75.370000] 010: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5
This commit is contained in:
@@ -71,36 +71,32 @@ static void spi_fpga_trans_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct spi_fpga_port *port =
|
||||
container_of(work, struct spi_fpga_port, fpga_trans_work);
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&port->work_lock, flags);
|
||||
while (!list_empty(&port->trans_queue))
|
||||
{
|
||||
spin_unlock_irqrestore(&port->work_lock, flags);
|
||||
struct spi_fpga_transfer *t = NULL, *tmp;
|
||||
list_for_each_entry_safe(t, tmp, &port->trans_queue, queue)
|
||||
{
|
||||
|
||||
if (t->id == 0)
|
||||
break;
|
||||
DBG("%s:id=%d,txbuf=0x%x\n",__FUNCTION__,t->id,(int)t->txbuf);
|
||||
switch(t->id)
|
||||
{
|
||||
case ID_SPI_FPGA_WRITE:
|
||||
spi_write(port->spi, t->txbuf, t->n_tx);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
kfree(t->txbuf);
|
||||
kfree(t);
|
||||
}
|
||||
while (1) {
|
||||
unsigned long flags;
|
||||
struct spi_fpga_transfer *t = NULL;
|
||||
|
||||
spin_lock_irqsave(&port->work_lock, flags);
|
||||
list_del_init(&port->trans_queue);
|
||||
if (!list_empty(&port->trans_queue)) {
|
||||
t = list_first_entry(&port->trans_queue, struct spi_fpga_transfer, queue);
|
||||
list_del(&t->queue);
|
||||
}
|
||||
spin_unlock_irqrestore(&port->work_lock, flags);
|
||||
|
||||
if (!t) // trans_queue empty
|
||||
break;
|
||||
|
||||
DBG("%s:id=%d,txbuf=0x%x\n",__FUNCTION__,t->id,(int)t->txbuf);
|
||||
switch (t->id) {
|
||||
case ID_SPI_FPGA_WRITE:
|
||||
spi_write(port->spi, t->txbuf, t->n_tx);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
kfree(t->txbuf);
|
||||
kfree(t);
|
||||
}
|
||||
spin_unlock_irqrestore(&port->work_lock, flags);
|
||||
|
||||
}
|
||||
|
||||
int spi_write_work(struct spi_device *spi, u8 *buf, size_t len)
|
||||
@@ -129,8 +125,8 @@ int spi_write_work(struct spi_device *spi, u8 *buf, size_t len)
|
||||
|
||||
spin_lock_irqsave(&port->work_lock, flags);
|
||||
list_add_tail(&t->queue, &port->trans_queue);
|
||||
queue_work(port->fpga_trans_workqueue, &port->fpga_trans_work);
|
||||
spin_unlock_irqrestore(&port->work_lock, flags);
|
||||
queue_work(port->fpga_trans_workqueue, &port->fpga_trans_work);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -685,43 +681,43 @@ static int spi_fpga_wait_suspend(struct spi_fpga_port *port)
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void fpga_close_power_support(void)
|
||||
{
|
||||
//cmmb power down
|
||||
gpio_request(FPGA_PIO4_03, NULL);
|
||||
gpio_direction_output(FPGA_PIO4_03,GPIO_LOW);
|
||||
gpio_free(FPGA_PIO4_03);
|
||||
gpio_request(FPGA_PIO2_09, NULL);
|
||||
gpio_direction_output(FPGA_PIO2_09,GPIO_LOW);
|
||||
gpio_free(FPGA_PIO2_09);
|
||||
gpio_request(FPGA_PIO2_06, NULL);
|
||||
gpio_direction_output(FPGA_PIO2_06,GPIO_LOW);
|
||||
gpio_free(FPGA_PIO2_06);
|
||||
|
||||
//KEY LED control
|
||||
gpio_request(FPGA_PIO1_13, NULL);
|
||||
gpio_direction_output(FPGA_PIO1_13,GPIO_LOW);
|
||||
gpio_free(FPGA_PIO1_13);
|
||||
}
|
||||
|
||||
static void fpga_open_power_support(void)
|
||||
{
|
||||
//cmmb do not control here
|
||||
|
||||
//KEY LED resume
|
||||
gpio_request(FPGA_PIO1_13, NULL);
|
||||
gpio_direction_output(FPGA_PIO1_13,GPIO_HIGH);
|
||||
gpio_free(FPGA_PIO1_13);
|
||||
}
|
||||
|
||||
static void fpga_close_power_support(void)
|
||||
{
|
||||
//cmmb power down
|
||||
gpio_request(FPGA_PIO4_03, NULL);
|
||||
gpio_direction_output(FPGA_PIO4_03,GPIO_LOW);
|
||||
gpio_free(FPGA_PIO4_03);
|
||||
gpio_request(FPGA_PIO2_09, NULL);
|
||||
gpio_direction_output(FPGA_PIO2_09,GPIO_LOW);
|
||||
gpio_free(FPGA_PIO2_09);
|
||||
gpio_request(FPGA_PIO2_06, NULL);
|
||||
gpio_direction_output(FPGA_PIO2_06,GPIO_LOW);
|
||||
gpio_free(FPGA_PIO2_06);
|
||||
|
||||
//KEY LED control
|
||||
gpio_request(FPGA_PIO1_13, NULL);
|
||||
gpio_direction_output(FPGA_PIO1_13,GPIO_LOW);
|
||||
gpio_free(FPGA_PIO1_13);
|
||||
}
|
||||
|
||||
static void fpga_open_power_support(void)
|
||||
{
|
||||
//cmmb do not control here
|
||||
|
||||
//KEY LED resume
|
||||
gpio_request(FPGA_PIO1_13, NULL);
|
||||
gpio_direction_output(FPGA_PIO1_13,GPIO_HIGH);
|
||||
gpio_free(FPGA_PIO1_13);
|
||||
}
|
||||
|
||||
static int spi_fpga_suspend(struct spi_device *spi, pm_message_t state)
|
||||
{
|
||||
|
||||
struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);
|
||||
fpga_close_power_support( );
|
||||
struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);
|
||||
int ret;
|
||||
fpga_close_power_support( );
|
||||
ret = spi_fpga_wait_suspend(port);
|
||||
if(!ret)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user