/** * @brief Card un-initial function. * @param work[in]: Work structure. * @return None. */ static void gp_sdcard_work_uninit(struct work_struct *work) { gpSDInfo_t* sd = container_of(work, gpSDInfo_t,uninit); if(sd->card_type == SDIO) { gp_sdio_remove_device(); gp_board_pin_func_release(sd->pin_handle); } else { /* ----- Stop new requests from getting into the queue ----- */ del_gendisk(sd->gd); /* ----- Then terminate our worker thread ----- */ kthread_stop(sd->thread); if (sd->sg) kfree(sd->sg); sd->sg = NULL; blk_cleanup_queue (sd->queue); put_disk(sd->gd); /* ----- free dma channel ----- */ if(sd->handle_dma) gp_apbdma0_release(sd->handle_dma); sd->handle_dma = 0; } /* ----- Uninitial SD controller ----- */ gpHalSDUninit(sd->device_id); sd->users = 0; sd->timer.expires = jiffies + SD_CD_POLL; add_timer(&sd->timer); }
/** * @brief Scatter list data transfer function. * @param sd[in]: Card information. * @param sector[in]: Start sector. * @param sg[in]: Scatter list pointer. * @param ln[in]: List number. * @return Actual sectors by reading/ERROR_ID(<0). */ static int gp_sdcard_transfer_scatter(gpSDInfo_t *sd, unsigned long sector, struct scatterlist *sg, unsigned int ln, int write) { int ret; int pin_handle; /* ----- Check card status ----- */ if((gp_sdcard_ckinsert(sd)==0)||(sd->handle_dma==0)) return -ENXIO; /* ----- Get pin handle ----- */ pin_handle = gp_board_pin_func_request((sd->device_id==0)?GP_PIN_SD0:GP_PIN_SD1, GP_BOARD_WAIT_FOREVER); if(pin_handle<0) { DERROR("SD%d: can't get pin handle\n", sd->device_id); return -EIO; } if(write==0) { ret = gp_sdcard_read_scatter(sd, sector, sg, ln); } else { /* ----- Check write protect ----- */ if(sd->sd_func->is_write_protected()==1) ret = -EROFS; else ret = gp_sdcard_write_scatter(sd, sector, sg, ln); } gp_board_pin_func_release(pin_handle); return ret; }
/** * @brief spi device remove */ static int gp_spi_remove(struct platform_device *pdev) { gp_board_pin_func_release(gp_spi_data->pin_handle); gpHalSpiClkEnable(&gp_spi_device.dev, 0); misc_deregister(&gp_spi_data->dev); kfree(gp_spi_data); return 0; }
static int32_t lcd_suspend( void ) { printk("[%s:%d]\n", __FUNCTION__, __LINE__); gpHalLcdClkEnable(0); #ifdef CONFIG_PM gp_enable_clock((int*)"READLTIME_ABT", 0); #endif /* board config : release pin function */ gp_board_pin_func_release(g_pin_func_handle); return 0; }
/** * @brief spi device probe */ static int gp_spi_probe(struct platform_device *pdev) { int ret = 0; gp_spi_data = kzalloc(sizeof(gp_spi_t), GFP_KERNEL); if(!gp_spi_data){ return -ENOMEM; } memset(gp_spi_data, 0, sizeof(gp_spi_t)); gp_spi_data->pin_handle = gp_board_pin_func_request(GP_PIN_SPI, GP_BOARD_WAIT_FOREVER); if (gp_spi_data->pin_handle < 0) { DIAG_ERROR("[%s:%d] Error!\n", __FUNCTION__, __LINE__); ret = -EINVAL; goto fail_pin; } gp_spi_data->dev.name = SPI_NAME; gp_spi_data->dev.minor = MISC_DYNAMIC_MINOR; gp_spi_data->dev.fops = &spi_fops; gpHalSpiClkEnable(&gp_spi_device.dev, 1); ret = misc_register(&gp_spi_data->dev); if(ret != 0){ DIAG_ERROR("spi probe register fail\n"); goto fail_reg; } platform_set_drvdata(pdev,&gp_spi_data); init_MUTEX(&gp_spi_data->spi_sem); DIAG_INFO("spi probe ok\n"); return 0; fail_reg: gp_board_pin_func_release(gp_spi_data->pin_handle); gpHalSpiClkEnable(&gp_spi_device.dev, 0); fail_pin: kfree(gp_spi_data); return ret; }
/** * @brief Scatter list data transfer function. * @param sd[in]: Card information. * @param sector[in]: Start sector. * @param sg[in]: Scatter list pointer. * @param ln[in]: List number. * @return Actual sectors by reading/ERROR_ID(<0). */ static int gp_sdcard_transfer_scatter(gpSDInfo_t *sd, unsigned long sector, struct scatterlist *sg, unsigned int ln, int write) { int ret; int pin_handle; int pin_id; /* ----- Check card status ----- */ if(gp_sdcard_ckinsert(sd)==0) { sd->fremove = 1; return -ENXIO; } #ifdef PIN_REQUEST_FUNCTION if(sd->device_id == 0) pin_id = GP_PIN_SD0; else if(sd->device_id == 1) pin_id = GP_PIN_SD1; else pin_id = GP_PIN_SD2; /* ----- Get pin handle ----- */ pin_handle = gp_board_pin_func_request( pin_id, GP_BOARD_WAIT_FOREVER); if(pin_handle<0) { DERROR("[%d]: can't get pin handle\n", sd->device_id); return -EBUSY; } #endif if(write==0) { ret = gp_sdcard_read_scatter(sd, sector, sg, ln); } else { /* ----- Check write protect ----- */ if(sd->sd_func->is_write_protected()==1) ret = -EROFS; else ret = gp_sdcard_write_scatter(sd, sector, sg, ln); } #ifdef PIN_REQUEST_FUNCTION gp_board_pin_func_release(pin_handle); #endif return ret; }
static int32_t lcd_suspend( void ) { printk("[%s:%d]\n", __FUNCTION__, __LINE__); gpHalLcdClkEnable(0); #ifdef CONFIG_PM gp_enable_clock((int*)"READLTIME_ABT", 0); #endif if (R_TFT1_CTRL & 0x1) { R_SCUA_SYS_SEL |= 0x2; } else { /* board config : release pin function */ gp_board_pin_func_release(g_pin_func_handle); } return 0; }
/** * @brief Card un-initial function. * @param work[in]: Work structure. * @return None. */ static void gp_sdcard_work_uninit(struct work_struct *work) { gpSDInfo_t* sd = container_of(work, gpSDInfo_t,uninit); if(sd->card_type == SDIO) { gp_sdio_remove_device(); gp_board_pin_func_release(sd->pin_handle); } else { gp_sdcard_cleanup(sd); } memset (&sd->partition, 0, sizeof(partition_t)); /* ----- Uninitial SD controller ----- */ gp_sdcard_carduninit(sd); sd->fremove = 0; sd->status = 1; sd->present = 0; sd->timer.expires = jiffies + SD_CD_POLL; add_timer(&sd->timer); }
/** * @brief SD resume function. * @param pdev[in]: Platform device pointer. * @param state[in]: Suspend event. * @return SUCCESS/ERROR_ID. */ static int gp_sd_resume(struct platform_device *pdev) { int i; DEBUG("SD resume\n"); for(i = 0; i < SD_NUM; i++) { gpSDInfo_t *sd = &sd_info[i]; /* enable sd clock */ if( (sd->present==1) && (gp_sdcard_ckinsert(sd)==1) ) { if(gp_sdcard_inner_card(sd)) { int pin_handle; int pin_id; if(sd->device_id == 0) pin_id = GP_PIN_SD0; else if(sd->device_id == 1) pin_id = GP_PIN_SD1; else pin_id = GP_PIN_SD2; pin_handle = gp_board_pin_func_request( pin_id, GP_BOARD_WAIT_FOREVER); if(pin_handle<0) { DERROR("[%d]: can't get pin handle\n", sd->device_id); return -1; } gp_sdcard_cardinit(sd); gp_board_pin_func_release(pin_handle); } else sd->fremove = 1; } } return 0; }
/** * @brief Card initial function. * @param work[in]: Work structure. * @return None. */ static void gp_sdcard_work_init(struct work_struct *work) { gpSDInfo_t* sd = container_of(work, gpSDInfo_t,init); int pin_handle; pin_handle = gp_board_pin_func_request((sd->device_id==0)?GP_PIN_SD0:GP_PIN_SD1, GP_BOARD_WAIT_FOREVER); if(pin_handle<0) { DERROR("SD%d: can't get pin handle\n", sd->device_id); goto init_work_end; } /* ----- Initial SD module (controller) ----- */ gpHalSDInit(sd->device_id); /* ----- Initial SD card ----- */ gp_sdcard_cardinit(sd); gp_board_pin_func_release(pin_handle); if(sd->present==1) { if(sd->card_type == SDIO) { sd->pin_handle = gp_board_pin_func_request((sd->device_id==0)?GP_PIN_SD0:GP_PIN_SD1, GP_BOARD_WAIT_FOREVER); if(sd->pin_handle<0) { DERROR("SD%d: can't get pin handle\n", sd->device_id); goto init_work_end; } DEBUG("SDIO card detected\n"); gp_sdio_insert_device(sd->device_id, sd->RCA); } else { sd->queue = blk_init_queue(gp_sdcard_request, &sd->lock); if(sd->queue==NULL) { DERROR("NO MEMORY: queue\n"); goto init_work_end; } blk_queue_ordered(sd->queue, QUEUE_ORDERED_DRAIN, NULL); queue_flag_set_unlocked(QUEUE_FLAG_NONROT, sd->queue); blk_queue_logical_block_size(sd->queue, 512); blk_queue_max_sectors(sd->queue, SD_MAX_SECTORS ); blk_queue_max_phys_segments(sd->queue, SD_MAX_PHY_SEGMENTS); blk_queue_max_hw_segments(sd->queue, SD_MAX_HW_SEGMENTS); blk_queue_max_segment_size(sd->queue, SD_MAX_PHY_SEGMENTS_SIZE); /* ----- Initial scatter list ----- */ sd->sg = kmalloc(sizeof(struct scatterlist) *SD_MAX_PHY_SEGMENTS, GFP_KERNEL); if (!sd->sg) { DERROR("NO MEMORY: queue\n"); goto fail_thread; } sg_init_table(sd->sg, SD_MAX_PHY_SEGMENTS); init_MUTEX(&sd->thread_sem); /* ----- Enable thread ----- */ sd->thread = kthread_run(gp_sdcard_queue_thread, sd, "sd-qd"); if (IS_ERR(sd->thread)) { goto fail_thread; } sd->queue->queuedata = sd; /* ----- Setup gendisk structure ----- */ sd->gd = alloc_disk(SD_MINORS); if (sd->gd==NULL) { DERROR("NO MEMORY: gendisk\n"); blk_cleanup_queue(sd->queue); goto fail_gd; } /* ----- Set gendisk structure ----- */ sd->gd->major = sd_major; sd->gd->first_minor = sd->device_id*SD_MINORS; sd->gd->fops = &gp_sdcard_ops; sd->gd->queue = sd->queue; sd->gd->private_data = sd; snprintf (sd->gd->disk_name, 32, "sdcard%c", sd->device_id + 'a'); set_capacity(sd->gd,sd->capacity); add_disk(sd->gd); } goto init_work_end; } else { DERROR("Initial fail\n"); goto init_work_end; } fail_gd: /* ----- Then terminate our worker thread ----- */ kthread_stop(sd->thread); fail_thread: if (sd->sg) kfree(sd->sg); sd->sg = NULL; blk_cleanup_queue (sd->queue); init_work_end: sd->timer.expires = jiffies + SD_CD_POLL; add_timer(&sd->timer); }
/** * @brief Card initial function. * @param work[in]: Work structure. * @return None. */ static void gp_sdcard_work_init(struct work_struct *work) { gpSDInfo_t* sd = container_of(work, gpSDInfo_t,init); int pin_handle; int ret = 0,i=0; int pin_id; if(sd->device_id == 0) pin_id = GP_PIN_SD0; else if(sd->device_id == 1) pin_id = GP_PIN_SD1; else pin_id = GP_PIN_SD2; pin_handle = gp_board_pin_func_request( pin_id, GP_BOARD_WAIT_FOREVER); if(pin_handle<0) { DERROR("[%d]: can't get pin handle\n", sd->device_id); goto init_work_end; } /* ----- chris: Set Pin state for SD before power on ----- */ sd->sd_func->set_power(1); /* ----- chris: delay 250ms after card power on ----- */ msleep(250); /* ----- Initial SD card ----- */ ret = gp_sdcard_cardinit(sd); if (ret != 0) { DERROR("[%d]: initial fail\n",sd->device_id); gp_board_pin_func_release(pin_handle); goto init_work_end; } gp_board_pin_func_release(pin_handle); if(sd->present==1) { if(sd->card_type == SDIO) { sd->pin_handle = gp_board_pin_func_request(pin_id, GP_BOARD_WAIT_FOREVER); if(sd->pin_handle<0) { DERROR("[%d]: can't get pin handle\n", sd->device_id); goto init_work_end; } DEBUG("SDIO card detected\n"); gp_sdio_insert_device(sd->device_id, sd->RCA); } else { unsigned int cnt =0; /* ----- Wait 30 second for all process close handle ----- */ while((sd->users)&&cnt<120) { msleep(250); cnt++; } if(sd->users) { DERROR("Some handle do not free\n"); } if(sd->status) { gp_sdcard_blk_put(sd); sd->status = 0; } sd->handle_dma = gp_apbdma0_request(1000); if(sd->handle_dma==0) goto init_work_end; sd->queue = blk_init_queue(gp_sdcard_request, &sd->lock); if(sd->queue==NULL) { DERROR("NO MEMORY: queue\n"); goto fail_queue; } blk_queue_ordered(sd->queue, QUEUE_ORDERED_DRAIN, NULL); queue_flag_set_unlocked(QUEUE_FLAG_NONROT, sd->queue); blk_queue_logical_block_size(sd->queue, 512); blk_queue_max_sectors(sd->queue, SD_MAX_SECTORS ); blk_queue_max_phys_segments(sd->queue, SD_MAX_PHY_SEGMENTS); blk_queue_max_hw_segments(sd->queue, SD_MAX_HW_SEGMENTS); blk_queue_max_segment_size(sd->queue, SD_MAX_PHY_SEGMENTS_SIZE); /* ----- Initial scatter list ----- */ sd->sg = kmalloc(sizeof(struct scatterlist) *SD_MAX_PHY_SEGMENTS, GFP_KERNEL); if (!sd->sg) { DERROR("NO MEMORY: queue\n"); goto fail_thread; } sg_init_table(sd->sg, SD_MAX_PHY_SEGMENTS); init_MUTEX(&sd->thread_sem); /* ----- Enable thread ----- */ sd->thread = kthread_run(gp_sdcard_queue_thread, sd, "sd-qd"); if (IS_ERR(sd->thread)) { goto fail_thread; } sd->queue->queuedata = sd; /* ----- Check SD card for GP special header ----- */ if(gp_sdcard_parse_header(sd)<0) { goto fail_gd; } /* ----- Setup gendisk structure ----- */ sd->gd = alloc_disk(SD_MINORS); if (sd->gd==NULL) { DERROR("NO MEMORY: gendisk\n"); blk_cleanup_queue(sd->queue); goto fail_gd; } /* ----- Set gendisk structure ----- */ sd->gd->major = sd_major; sd->gd->first_minor = sd->device_id*SD_MINORS; sd->gd->fops = &gp_sdcard_ops; sd->gd->queue = sd->queue; sd->gd->private_data = sd; snprintf (sd->gd->disk_name, 32, "sdcard%c", sd->device_id + 'a'); /* ----- Set GP partition ----- */ if(sd->partition.activity) { set_capacity(sd->gd,0); add_disk(sd->gd); for(i=0;i<MAX_SD_PART;i++) { if(sd->partition.capacity[i]==0) continue; gp_add_partition(sd->gd,i+1,sd->partition.offset[i],sd->partition.capacity[i],ADDPART_FLAG_WHOLEDISK); } } /* ----- Normal Setting ----- */ else { set_capacity(sd->gd,sd->capacity); add_disk(sd->gd); } } //DEBUG("Initial success\n"); goto init_work_end; } else { DERROR("Initial fail\n"); goto init_work_end; } fail_gd: /* ----- Then terminate our worker thread ----- */ kthread_stop(sd->thread); sd->thread = NULL; fail_thread: if (sd->sg) kfree(sd->sg); sd->sg = NULL; blk_cleanup_queue (sd->queue); sd->queue = NULL; fail_queue: if(sd->handle_dma) gp_apbdma0_release(sd->handle_dma); sd->handle_dma = 0; /* ----- For re-initialize ----- */ sd->present = 0; init_work_end: sd->timer.expires = jiffies + SD_CD_POLL; add_timer(&sd->timer); }