diff options
author | Thomas White <taw@bitwiz.org.uk> | 2009-04-25 19:23:57 +0100 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2009-04-25 19:23:57 +0100 |
commit | ca8cdf043c7c6d8e1b4b3d86f3cae12fc37756a2 (patch) | |
tree | dad605a1b3142e85d9ddc08a77d62f6bf09f22cc | |
parent | 16696dd08020690cff796fc4705b4d6bd14e91b0 (diff) | |
parent | b4136a36f31a65d0998a328465df9e8e2ba93166 (diff) |
Merge branch 'andy-tracking' into drm-tracking
Conflicts:
drivers/mfd/glamo/Kconfig
31 files changed, 597 insertions, 418 deletions
diff --git a/arch/arm/configs/gta02_micro_defconfig b/arch/arm/configs/gta02_micro_defconfig index b81e96dbf09..ae30c4b1ddb 100644 --- a/arch/arm/configs/gta02_micro_defconfig +++ b/arch/arm/configs/gta02_micro_defconfig @@ -707,6 +707,7 @@ CONFIG_PCF50633_GPIO=y # CONFIG_MFD_PCF50606 is not set CONFIG_MFD_GLAMO=y CONFIG_MFD_GLAMO_FB=y +CONFIG_MFD_GLAMO_FB_XGLAMO_WORKAROUND=y CONFIG_MFD_GLAMO_SPI_GPIO=y CONFIG_MFD_GLAMO_SPI_FB=y CONFIG_MFD_GLAMO_MCI=y diff --git a/arch/arm/configs/gta02_moredrivers_defconfig b/arch/arm/configs/gta02_moredrivers_defconfig index 94698ada167..1dbbbf63ce8 100644 --- a/arch/arm/configs/gta02_moredrivers_defconfig +++ b/arch/arm/configs/gta02_moredrivers_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.29-rc3 -# Tue Feb 24 02:11:01 2009 +# Sun Apr 19 23:22:38 2009 # CONFIG_ARM=y CONFIG_HAVE_PWM=y @@ -204,6 +204,7 @@ CONFIG_S3C_GPIO_SPACE=0 CONFIG_S3C_GPIO_TRACK=y CONFIG_S3C_DMA=y CONFIG_S3C_PWM=y +CONFIG_S3C_DEV_USB_HOST=y # # S3C2400 Machines @@ -1029,8 +1030,8 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_CM109 is not set CONFIG_INPUT_UINPUT=m -CONFIG_INPUT_PCF50633_PMU=y CONFIG_INPUT_LIS302DL=y +CONFIG_INPUT_PCF50633_PMU=y # # Hardware I/O ports @@ -1279,6 +1280,7 @@ CONFIG_PCF50633_GPIO=y # CONFIG_MFD_PCF50606 is not set CONFIG_MFD_GLAMO=y CONFIG_MFD_GLAMO_FB=y +CONFIG_MFD_GLAMO_FB_XGLAMO_WORKAROUND=y CONFIG_MFD_GLAMO_SPI_GPIO=y CONFIG_MFD_GLAMO_SPI_FB=y CONFIG_MFD_GLAMO_MCI=y @@ -1800,17 +1802,13 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=y -CONFIG_EXT4DEV_COMPAT=y -CONFIG_EXT4_FS_XATTR=y -# CONFIG_EXT4_FS_POSIX_ACL is not set -CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set -CONFIG_JBD2=y -# CONFIG_JBD2_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set CONFIG_FILE_LOCKING=y diff --git a/arch/arm/configs/gta02_packaging_defconfig b/arch/arm/configs/gta02_packaging_defconfig index 5f9aa9338e9..237fd959510 100644 --- a/arch/arm/configs/gta02_packaging_defconfig +++ b/arch/arm/configs/gta02_packaging_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.29-rc3 -# Tue Feb 24 02:12:40 2009 +# Sun Apr 19 22:57:25 2009 # CONFIG_ARM=y CONFIG_HAVE_PWM=y @@ -204,6 +204,7 @@ CONFIG_S3C_GPIO_SPACE=0 CONFIG_S3C_GPIO_TRACK=y CONFIG_S3C_DMA=y CONFIG_S3C_PWM=y +CONFIG_S3C_DEV_USB_HOST=y # # S3C2400 Machines @@ -1032,8 +1033,8 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_CM109 is not set CONFIG_INPUT_UINPUT=m -CONFIG_INPUT_PCF50633_PMU=y CONFIG_INPUT_LIS302DL=y +CONFIG_INPUT_PCF50633_PMU=y # # Hardware I/O ports @@ -1282,6 +1283,7 @@ CONFIG_PCF50633_GPIO=y # CONFIG_MFD_PCF50606 is not set CONFIG_MFD_GLAMO=y CONFIG_MFD_GLAMO_FB=y +CONFIG_MFD_GLAMO_FB_XGLAMO_WORKAROUND=y CONFIG_MFD_GLAMO_SPI_GPIO=y CONFIG_MFD_GLAMO_SPI_FB=y CONFIG_MFD_GLAMO_MCI=y @@ -1803,17 +1805,13 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=y -CONFIG_EXT4DEV_COMPAT=y -CONFIG_EXT4_FS_XATTR=y -# CONFIG_EXT4_FS_POSIX_ACL is not set -CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set -CONFIG_JBD2=y -# CONFIG_JBD2_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y CONFIG_FILE_LOCKING=y @@ -1894,7 +1892,6 @@ CONFIG_NFS_FS=m CONFIG_NFS_V3=y CONFIG_NFS_V3_ACL=y # CONFIG_NFS_V4 is not set -CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V2_ACL=y CONFIG_NFSD_V3=y diff --git a/arch/arm/mach-s3c2410/mach-gta01.c b/arch/arm/mach-s3c2410/mach-gta01.c index c5961d49ad8..bddba990a74 100644 --- a/arch/arm/mach-s3c2410/mach-gta01.c +++ b/arch/arm/mach-s3c2410/mach-gta01.c @@ -708,32 +708,32 @@ static struct s3c2410_udc_mach_info gta01_udc_cfg = { /* Touchscreen configuration. */ #ifdef CONFIG_TOUCHSCREEN_FILTER -static struct ts_filter_group_configuration gta01_ts_group = { +const static struct ts_filter_group_configuration gta01_ts_group = { .length = 12, .close_enough = 10, .threshold = 6, /* At least half of the points in a group. */ .attempts = 10, }; -static struct ts_filter_median_configuration gta01_ts_median = { +const static struct ts_filter_median_configuration gta01_ts_median = { .extent = 20, .decimation_below = 3, .decimation_threshold = 8 * 3, .decimation_above = 4, }; -static struct ts_filter_mean_configuration gta01_ts_mean = { +const static struct ts_filter_mean_configuration gta01_ts_mean = { .length = 4, }; -static struct ts_filter_linear_configuration gta01_ts_linear = { +const static struct ts_filter_linear_configuration gta01_ts_linear = { .constants = {1, 0, 0, 0, 1, 0, 1}, /* Don't modify coords. */ .coord0 = 0, .coord1 = 1, }; #endif -struct ts_filter_chain_configuration filter_configuration[] = +const static struct ts_filter_chain_configuration gta01_filter_configuration[] = { #ifdef CONFIG_TOUCHSCREEN_FILTER {&ts_filter_group_api, >a01_ts_group.config}, @@ -744,10 +744,10 @@ struct ts_filter_chain_configuration filter_configuration[] = {NULL, NULL}, }; -static struct s3c2410_ts_mach_info gta01_ts_cfg = { +const static struct s3c2410_ts_mach_info gta01_ts_cfg = { .delay = 10000, .presc = 0xff, /* slow as we can go */ - .filter_config = filter_configuration, + .filter_config = gta01_filter_configuration, }; /* SPI */ diff --git a/arch/arm/mach-s3c2442/mach-gta02.c b/arch/arm/mach-s3c2442/mach-gta02.c index d469d033afd..072abd56759 100644 --- a/arch/arm/mach-s3c2442/mach-gta02.c +++ b/arch/arm/mach-s3c2442/mach-gta02.c @@ -986,7 +986,7 @@ const static struct ts_filter_linear_configuration gta02_ts_linear = { }; #endif -const struct ts_filter_chain_configuration filter_configuration[] = +const static struct ts_filter_chain_configuration gta02_filter_configuration[] = { #ifdef CONFIG_TOUCHSCREEN_FILTER {&ts_filter_group_api, >a02_ts_group.config}, @@ -1000,7 +1000,7 @@ const struct ts_filter_chain_configuration filter_configuration[] = const static struct s3c2410_ts_mach_info gta02_ts_cfg = { .delay = 10000, .presc = 0xff, /* slow as we can go */ - .filter_config = filter_configuration, + .filter_config = gta02_filter_configuration, }; @@ -1027,16 +1027,17 @@ static void gta02_bl_set_intensity(int intensity) return; } - old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT); + if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 3)) + old_intensity = 0; + else + old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT); + if (intensity == old_intensity) return; /* We can't do this anywhere else */ pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 5); - if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 3)) - old_intensity = 0; - /* * The PCF50633 cannot handle LEDOUT = 0 (datasheet p60) * if seen, you have to re-enable the LED unit diff --git a/arch/arm/plat-s3c/dev-usb.c b/arch/arm/plat-s3c/dev-usb.c index 2ee85abed6d..721ff18f438 100644 --- a/arch/arm/plat-s3c/dev-usb.c +++ b/arch/arm/plat-s3c/dev-usb.c @@ -37,7 +37,7 @@ static struct resource s3c_usb_resource[] = { static u64 s3c_device_usb_dmamask = 0xffffffffUL; struct platform_device s3c_device_usb = { - .name = "s3c2410-ohci", + .name = "s3c-ohci", .id = -1, .num_resources = ARRAY_SIZE(s3c_usb_resource), .resource = s3c_usb_resource, diff --git a/arch/arm/plat-s3c/init.c b/arch/arm/plat-s3c/init.c index 94a3120f561..c1ddac1007c 100644 --- a/arch/arm/plat-s3c/init.c +++ b/arch/arm/plat-s3c/init.c @@ -52,7 +52,8 @@ static void __init set_system_rev(unsigned int idcode) if (idcode == 0x32410002 || idcode == 0x32440001) system_rev |= (0x1 << 16); - if (idcode == 0x32440aaa) /* s3c2442 */ + if (idcode == 0x32440aaa /* s3c2442 */ + || idcode == 0x32440aab) /* s3c2442b */ system_rev |= (0x2 << 16); if (idcode == 0x0) /* s3c2400 */ system_rev |= (0x2400 << 16); diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_gps.c b/arch/arm/plat-s3c24xx/neo1973_pm_gps.c index b5322f200b4..93b491137e7 100644 --- a/arch/arm/plat-s3c24xx/neo1973_pm_gps.c +++ b/arch/arm/plat-s3c24xx/neo1973_pm_gps.c @@ -764,6 +764,7 @@ static int gta01_pm_gps_remove(struct platform_device *pdev) regulator_put(neo1973_gps.regulator[i]); } #endif + bus_remove_device_link(&platform_bus_type, "gta01-pm-gps.0"); sysfs_remove_group(&pdev->dev.kobj, >a01_gps_attr_group); } diff --git a/drivers/ar6000/ar6000/ar6000_drv.c b/drivers/ar6000/ar6000/ar6000_drv.c index 816557641de..b790670ece8 100644 --- a/drivers/ar6000/ar6000/ar6000_drv.c +++ b/drivers/ar6000/ar6000/ar6000_drv.c @@ -238,6 +238,8 @@ static void ar6000_tx_complete(void *Context, HTC_PACKET *pPacket); static void ar6000_tx_queue_full(void *Context, HTC_ENDPOINT_ID Endpoint); +static void ar6000_tx_queue_avail(void *Context, HTC_ENDPOINT_ID Endpoint); + /* * Static variables */ @@ -972,86 +974,17 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) return; } - /* Stop the transmit queues */ - netif_stop_queue(dev); - - /* Disable the target and the interrupts associated with it */ - if (ar->arWmiReady == TRUE) - { - if (!bypasswmi) - { - if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) - { - AR_DEBUG_PRINTF("%s(): Disconnect\n", __func__); - AR6000_SPIN_LOCK(&ar->arLock, 0); - ar6000_init_profile_info(ar); - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - wmi_disconnect_cmd(ar->arWmi); - } - - ar6000_dbglog_get_debug_logs(ar); - ar->arWmiReady = FALSE; - ar->arConnected = FALSE; - ar->arConnectPending = FALSE; - wmi_shutdown(ar->arWmi); - ar->arWmiEnabled = FALSE; - ar->arWmi = NULL; - ar->arWlanState = WLAN_ENABLED; -#ifdef USER_KEYS - ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT; - ar->user_key_ctrl = 0; -#endif - } - - AR_DEBUG_PRINTF("%s(): WMI stopped\n", __func__); - } - else - { - AR_DEBUG_PRINTF("%s(): WMI not ready 0x%08x 0x%08x\n", - __func__, (unsigned int) ar, (unsigned int) ar->arWmi); - - /* Shut down WMI if we have started it */ - if(ar->arWmiEnabled == TRUE) - { - AR_DEBUG_PRINTF("%s(): Shut down WMI\n", __func__); - wmi_shutdown(ar->arWmi); - ar->arWmiEnabled = FALSE; - ar->arWmi = NULL; - } - } - - /* stop HTC */ - HTCStop(ar->arHtcTarget); - - /* set the instance to NULL so we do not get called back on remove incase we - * we're explicity destroyed by module unload */ - HTCSetInstance(ar->arHtcTarget, NULL); - - if (resetok) { - /* try to reset the device if we can - * The driver may have been configure NOT to reset the target during - * a debug session */ - AR_DEBUG_PRINTF(" Attempting to reset target on instance destroy.... \n"); - ar6000_reset_device(ar->arHifDevice, ar->arTargetType); - } else { - AR_DEBUG_PRINTF(" Host does not want target reset. \n"); - } - - /* Done with cookies */ - ar6000_cookie_cleanup(ar); - - /* Cleanup BMI */ - BMIInit(); - /* Clear the tx counters */ memset(tx_attempt, 0, sizeof(tx_attempt)); memset(tx_post, 0, sizeof(tx_post)); memset(tx_complete, 0, sizeof(tx_complete)); - /* Free up the device data structure */ - if (unregister) - unregister_netdev(dev); + if (unregister) { + unregister_netdev(dev); + } else { + ar6000_close(dev); + } free_raw_buffers(ar); @@ -1149,7 +1082,7 @@ static int ar6000_open(struct net_device *dev) { /* Wake up the queues */ - netif_wake_queue(dev); + netif_start_queue(dev); return 0; } @@ -1157,8 +1090,79 @@ ar6000_open(struct net_device *dev) static int ar6000_close(struct net_device *dev) { + AR_SOFTC_T *ar = netdev_priv(dev); + + /* Stop the transmit queues */ netif_stop_queue(dev); + /* Disable the target and the interrupts associated with it */ + if (ar->arWmiReady == TRUE) + { + if (!bypasswmi) + { + if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) + { + AR_DEBUG_PRINTF("%s(): Disconnect\n", __func__); + AR6000_SPIN_LOCK(&ar->arLock, 0); + ar6000_init_profile_info(ar); + AR6000_SPIN_UNLOCK(&ar->arLock, 0); + wmi_disconnect_cmd(ar->arWmi); + } + + ar6000_dbglog_get_debug_logs(ar); + ar->arWmiReady = FALSE; + ar->arConnected = FALSE; + ar->arConnectPending = FALSE; + wmi_shutdown(ar->arWmi); + ar->arWmiEnabled = FALSE; + ar->arWmi = NULL; + ar->arWlanState = WLAN_ENABLED; +#ifdef USER_KEYS + ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT; + ar->user_key_ctrl = 0; +#endif + } + + AR_DEBUG_PRINTF("%s(): WMI stopped\n", __func__); + } + else + { + AR_DEBUG_PRINTF("%s(): WMI not ready 0x%08x 0x%08x\n", + __func__, (unsigned int) ar, (unsigned int) ar->arWmi); + + /* Shut down WMI if we have started it */ + if(ar->arWmiEnabled == TRUE) + { + AR_DEBUG_PRINTF("%s(): Shut down WMI\n", __func__); + wmi_shutdown(ar->arWmi); + ar->arWmiEnabled = FALSE; + ar->arWmi = NULL; + } + } + + /* stop HTC */ + HTCStop(ar->arHtcTarget); + + /* set the instance to NULL so we do not get called back on remove incase we + * we're explicity destroyed by module unload */ + HTCSetInstance(ar->arHtcTarget, NULL); + + if (resetok) { + /* try to reset the device if we can + * The driver may have been configure NOT to reset the target during + * a debug session */ + AR_DEBUG_PRINTF(" Attempting to reset target on instance destroy.... \n"); + ar6000_reset_device(ar->arHifDevice, ar->arTargetType); + } else { + AR_DEBUG_PRINTF(" Host does not want target reset. \n"); + } + + /* Done with cookies */ + ar6000_cookie_cleanup(ar); + + /* Cleanup BMI */ + BMIInit(); + return 0; } @@ -1278,6 +1282,7 @@ int ar6000_init(struct net_device *dev) connect.EpCallbacks.EpRecv = ar6000_rx; connect.EpCallbacks.EpRecvRefill = ar6000_rx_refill; connect.EpCallbacks.EpSendFull = ar6000_tx_queue_full; + connect.EpCallbacks.EpSendAvail = ar6000_tx_queue_avail; /* set the max queue depth so that our ar6000_tx_queue_full handler gets called. * Linux has the peculiarity of not providing flow control between the * NIC and the network stack. There is no API to indicate that a TX packet @@ -1753,10 +1758,10 @@ applyAPTCHeuristics(AR_SOFTC_T *ar) } #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ -static void ar6000_tx_queue_full(void *Context, HTC_ENDPOINT_ID Endpoint) +static void +ar6000_tx_queue_full(void *Context, HTC_ENDPOINT_ID Endpoint) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; - + AR_SOFTC_T *ar = (AR_SOFTC_T *) Context; if (Endpoint == arWMIStream2EndpointID(ar,WMI_CONTROL_PRI)) { if (!bypasswmi) { @@ -1771,19 +1776,26 @@ static void ar6000_tx_queue_full(void *Context, HTC_ENDPOINT_ID Endpoint) AR_DEBUG_PRINTF("WMI Control Endpoint is FULL!!! \n"); } } else { - - AR6000_SPIN_LOCK(&ar->arLock, 0); - ar->arNetQueueStopped = TRUE; - AR6000_SPIN_UNLOCK(&ar->arLock, 0); /* one of the data endpoints queues is getting full..need to stop network stack - * the queue will resume in ar6000_tx_complete() */ + * the queue will resume after credits received */ netif_stop_queue(ar->arNetDev); } +} +static void +ar6000_tx_queue_avail(void *Context, HTC_ENDPOINT_ID Endpoint) +{ + AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; + if (Endpoint == arWMIStream2EndpointID(ar,WMI_CONTROL_PRI)) { + /* FIXME: what do for it? */ + } else { + /* Wake up interface, rescheduling prevented. */ + if (ar->arConnected == TRUE || bypasswmi) + netif_wake_queue(ar->arNetDev); + } } - static void ar6000_tx_complete(void *Context, HTC_PACKET *pPacket) { @@ -1877,10 +1889,6 @@ ar6000_tx_complete(void *Context, HTC_PACKET *pPacket) ar6000_free_cookie(ar, cookie); } - if (ar->arNetQueueStopped) { - ar->arNetQueueStopped = FALSE; - } - AR6000_SPIN_UNLOCK(&ar->arLock, 0); /* lock is released, we can freely call other kernel APIs */ @@ -1888,18 +1896,9 @@ ar6000_tx_complete(void *Context, HTC_PACKET *pPacket) /* this indirectly frees the HTC_PACKET */ A_NETBUF_FREE(skb); - if ((ar->arConnected == TRUE) || (bypasswmi)) { - if (status != A_ECANCELED) { - /* don't wake the queue if we are flushing, other wise it will just - * keep queueing packets, which will keep failing */ - netif_wake_queue(ar->arNetDev); - } - } - if (wakeEvent) { wake_up(&arEvent); } - } /* @@ -2317,7 +2316,7 @@ ar6000_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, A_UINT8 *bssid, /* flush data queues */ ar6000_TxDataCleanup(ar); - netif_wake_queue(ar->arNetDev); + netif_start_queue(ar->arNetDev); if ((OPEN_AUTH == ar->arDot11AuthMode) && (NONE_AUTH == ar->arAuthMode) && diff --git a/drivers/ar6000/ar6000/ar6000_drv.h b/drivers/ar6000/ar6000/ar6000_drv.h index d5ff7774885..784f158d9c4 100644 --- a/drivers/ar6000/ar6000/ar6000_drv.h +++ b/drivers/ar6000/ar6000/ar6000_drv.h @@ -273,7 +273,6 @@ typedef struct ar6_softc { A_BOOL write_buffer_available[HTC_RAW_STREAM_NUM_MAX]; A_BOOL read_buffer_available[HTC_RAW_STREAM_NUM_MAX]; #endif - A_BOOL arNetQueueStopped; A_BOOL arRawIfInit; int arDeviceIndex; COMMON_CREDIT_STATE_INFO arCreditStateInfo; diff --git a/drivers/ar6000/ar6000/ar6000_raw_if.c b/drivers/ar6000/ar6000/ar6000_raw_if.c index 65402b9c8d5..4443bb26733 100644 --- a/drivers/ar6000/ar6000/ar6000_raw_if.c +++ b/drivers/ar6000/ar6000/ar6000_raw_if.c @@ -127,6 +127,7 @@ static A_STATUS ar6000_connect_raw_service(AR_SOFTC_T *ar, /* simple interface, we don't need these optional callbacks */ connect.EpCallbacks.EpRecvRefill = NULL; connect.EpCallbacks.EpSendFull = NULL; + connect.EpCallbacks.EpSendAvail = NULL; connect.MaxSendQueueDepth = RAW_HTC_WRITE_BUFFERS_NUM; /* connect to the raw streams service, we may be able to get 1 or more diff --git a/drivers/ar6000/ar6000/wireless_ext.c b/drivers/ar6000/ar6000/wireless_ext.c index d9a592038e6..af78ae05fcb 100644 --- a/drivers/ar6000/ar6000/wireless_ext.c +++ b/drivers/ar6000/ar6000/wireless_ext.c @@ -976,6 +976,16 @@ static int ar6000_ioctl_giwpower(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); + /* + * FIXME: + * https://docs.openmoko.org/trac/ticket/2267 + * When starting wpa_supplicant the kernel oopses. + * The following condition avoids the oops. + * Remove this comment to bless this solution. + */ + if (ar->arWlanState == WLAN_DISABLED || ar->arWmiReady == FALSE) + return -EIO; + return wmi_get_power_mode_cmd(ar->arWmi); } diff --git a/drivers/ar6000/hif/hif2.c b/drivers/ar6000/hif/hif2.c index 571833f2c79..386d96e668f 100644 --- a/drivers/ar6000/hif/hif2.c +++ b/drivers/ar6000/hif/hif2.c @@ -26,14 +26,28 @@ #include <linux/mmc/sdio_func.h> #include <linux/mmc/sdio.h> #include <linux/mmc/sdio_ids.h> -#include <asm/gpio.h> -#include <mach/gta02-pm-wlan.h> #include "athdefs.h" #include "a_types.h" #include "hif.h" +/* @@@ Hack - this wants cleaning up */ + +#ifdef CONFIG_MACH_NEO1973_GTA02 + +#include <mach/gta02-pm-wlan.h> + +#else /* CONFIG_MACH_NEO1973_GTA02 */ + +#define gta02_wlan_query_rfkill_lock() 1 +#define gta02_wlan_set_rfkill_cb(cb, hif) ((void) cb) +#define gta02_wlan_query_rfkill_unlock() +#define gta02_wlan_clear_rfkill_cb() + +#endif /* !CONFIG_MACH_NEO1973_GTA02 */ + + /* * KNOWN BUGS: * @@ -132,9 +146,6 @@ static DEFINE_MUTEX(shutdown_lock); /* ----- Request processing ------------------------------------------------ */ -#include <mach/regs-gpio.h> - - static A_STATUS process_request(struct hif_request *req) { int ret; @@ -143,16 +154,8 @@ static A_STATUS process_request(struct hif_request *req) dev_dbg(&req->func->dev, "process_request(req %p)\n", req); sdio_claim_host(req->func); if (req->read) { - while (!s3c2410_gpio_getpin(S3C2410_GPE7)) { - printk(KERN_INFO "READ WHILE BUSY !\n"); - yield(); - } ret = req->read(req->func, req->buf, req->addr, req->len); } else { - while (!s3c2410_gpio_getpin(S3C2410_GPE7)) { - printk(KERN_INFO "WRITE WHILE BUSY !\n"); - yield(); - } ret = req->write(req->func, req->addr, req->buf, req->len); } sdio_release_host(req->func); @@ -508,7 +511,8 @@ static int ar6000_do_activate(struct hif_device *hif) sdio_release_host(func); hif->io_task = kthread_run(io, hif, "ar6000_io"); - if (IS_ERR(hif->io_task)) { + ret = IS_ERR(hif->io_task); + if (ret) { dev_err(dev, "kthread_run(ar6000_io): %d\n", ret); goto out_func_ready; } @@ -580,8 +584,14 @@ static int ar6000_activate(struct hif_device *hif) mutex_lock(&hif->activate_lock); if (!hif->active) { ret = ar6000_do_activate(hif); + if (ret) { + printk(KERN_ERR "%s: Failed to activate %d\n", + __func__, ret); + goto out; + } hif->active = 1; } +out: mutex_unlock(&hif->activate_lock); return ret; } @@ -665,12 +675,12 @@ static void sdio_ar6000_remove(struct sdio_func *func) SDIO_DEVICE(SDIO_VENDOR_ID_ATHEROS, SDIO_DEVICE_ID_ATHEROS_##id | (offset)) static const struct sdio_device_id sdio_ar6000_ids[] = { - { ATHEROS_SDIO_DEVICE(AR6000, 0) }, - { ATHEROS_SDIO_DEVICE(AR6000, 0x1) }, - { ATHEROS_SDIO_DEVICE(AR6000, 0x8) }, - { ATHEROS_SDIO_DEVICE(AR6000, 0x9) }, - { ATHEROS_SDIO_DEVICE(AR6000, 0xa) }, - { ATHEROS_SDIO_DEVICE(AR6000, 0xb) }, + { ATHEROS_SDIO_DEVICE(AR6002, 0) }, + { ATHEROS_SDIO_DEVICE(AR6002, 0x1) }, + { ATHEROS_SDIO_DEVICE(AR6001, 0x8) }, + { ATHEROS_SDIO_DEVICE(AR6001, 0x9) }, + { ATHEROS_SDIO_DEVICE(AR6001, 0xa) }, + { ATHEROS_SDIO_DEVICE(AR6001, 0xb) }, { /* end: all zeroes */ }, }; diff --git a/drivers/ar6000/htc/htc.c b/drivers/ar6000/htc/htc.c index b5e691b962e..d52ed944e0d 100644 --- a/drivers/ar6000/htc/htc.c +++ b/drivers/ar6000/htc/htc.c @@ -283,7 +283,8 @@ A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle) connect.EpCallbacks.EpTxComplete = HTCControlTxComplete; connect.EpCallbacks.EpRecv = HTCControlRecv; connect.EpCallbacks.EpRecvRefill = NULL; /* not needed */ - connect.EpCallbacks.EpSendFull = NULL; /* not nedded */ + connect.EpCallbacks.EpSendFull = NULL; /* not needed */ + connect.EpCallbacks.EpSendAvail = NULL; /* not needed */ connect.MaxSendQueueDepth = NUM_CONTROL_BUFFERS; connect.ServiceID = HTC_CTRL_RSVD_SVC; diff --git a/drivers/ar6000/htc/htc_send.c b/drivers/ar6000/htc/htc_send.c index fd5ef6e2605..cf0dabef472 100644 --- a/drivers/ar6000/htc/htc_send.c +++ b/drivers/ar6000/htc/htc_send.c @@ -101,23 +101,22 @@ A_STATUS HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket, A_UINT8 SendFlags } /* try to send the current packet or a packet at the head of the TX queue, - * if there are no credits, the packet remains in the queue. - * this function always succeeds and returns a flag if the TX queue for - * the endpoint has hit the set limit */ -static A_BOOL HTCTrySend(HTC_TARGET *target, - HTC_ENDPOINT *pEndpoint, - HTC_PACKET *pPacketToSend) + * if there are no credits, the packet remains in the queue. */ +static void HTCTrySend(HTC_TARGET *target, + HTC_PACKET *pPacketToSend, + HTC_ENDPOINT_ID ep) { - HTC_PACKET *pPacket; - int creditsRequired; - int remainder; - A_UINT8 sendFlags; - A_BOOL epFull = FALSE; - - LOCK_HTC_TX(target); + HTC_PACKET *pPacket; + HTC_ENDPOINT *pEndpoint; + int creditsRequired; + A_UINT8 sendFlags; AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCTrySend (pPkt:0x%X)\n",(A_UINT32)pPacketToSend)); + pEndpoint = &target->EndPoint[ep]; + + LOCK_HTC_TX(target); + if (pPacketToSend != NULL) { /* caller supplied us a packet to queue to the tail of the HTC TX queue before * we check the tx queue */ @@ -143,12 +142,9 @@ static A_BOOL HTCTrySend(HTC_TARGET *target, (A_UINT32)pPacket, pEndpoint->CurrentTxQueueDepth)); /* figure out how many credits this message requires */ - creditsRequired = (pPacket->ActualLength + HTC_HDR_LENGTH) / target->TargetCreditSize; - remainder = (pPacket->ActualLength + HTC_HDR_LENGTH) % target->TargetCreditSize; - - if (remainder) { - creditsRequired++; - } + creditsRequired = pPacket->ActualLength + HTC_HDR_LENGTH; + creditsRequired += target->TargetCreditSize - 1; + creditsRequired /= target->TargetCreditSize; AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Creds Required:%d Got:%d\n", creditsRequired, pEndpoint->CreditDist.TxCredits)); @@ -212,14 +208,22 @@ static A_BOOL HTCTrySend(HTC_TARGET *target, } if (pEndpoint->CurrentTxQueueDepth >= pEndpoint->MaxTxQueueDepth) { - /* let caller know that this endpoint has reached the maximum depth */ - epFull = TRUE; + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Endpoint %d, TX queue is full, Depth:%d, Max:%d \n", + ep, pEndpoint->CurrentTxQueueDepth, pEndpoint->MaxTxQueueDepth)); + UNLOCK_HTC_TX(target); + /* queue is now full, let caller know */ + if (pEndpoint->EpCallBacks.EpSendFull != NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Calling driver's send full callback.... \n")); + pEndpoint->EpCallBacks.EpSendFull(pEndpoint->EpCallBacks.pContext, ep); + } + } else { + UNLOCK_HTC_TX(target); + /* queue is now available for new packet, let caller know */ + if (pEndpoint->EpCallBacks.EpSendAvail) + pEndpoint->EpCallBacks.EpSendAvail(pEndpoint->EpCallBacks.pContext, ep); } - UNLOCK_HTC_TX(target); - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend: \n")); - return epFull; } /* HTC API - HTCSendPkt */ @@ -251,20 +255,12 @@ A_STATUS HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket) pPacket->Completion = HTCSendPktCompletionHandler; pPacket->pContext = target; - if (HTCTrySend(target, pEndpoint, pPacket)) { - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Endpoint %d, TX queue is full, Depth:%d, Max:%d \n", - ep, pEndpoint->CurrentTxQueueDepth, pEndpoint->MaxTxQueueDepth)); - /* queue is now full, let caller know */ - if (pEndpoint->EpCallBacks.EpSendFull != NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Calling driver's send full callback.... \n")); - pEndpoint->EpCallBacks.EpSendFull(pEndpoint->EpCallBacks.pContext, - ep); - } - } + HTCTrySend(target, pPacket, ep); - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPkt \n")); } while (FALSE); + AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPkt \n")); + return status; } @@ -292,7 +288,7 @@ static INLINE void HTCCheckEndpointTxQueues(HTC_TARGET *target) * Highest priority queue get's processed first, if there are credits available the * highest priority queue will get a chance to reclaim credits from lower priority * ones */ - HTCTrySend(target, pEndpoint, NULL); + HTCTrySend(target, NULL, pDistItem->Endpoint); } pDistItem = pDistItem->pNext; @@ -480,7 +476,6 @@ void HTCFlushSendPkts(HTC_TARGET *target) HTCFlushEndpointTX(target,pEndpoint,HTC_TX_PACKET_TAG_ALL); } - } /* HTC API to flush an endpoint's TX queue*/ diff --git a/drivers/ar6000/include/htc_api.h b/drivers/ar6000/include/htc_api.h index 73b7df60ed0..e75692d7efa 100644 --- a/drivers/ar6000/include/htc_api.h +++ b/drivers/ar6000/include/htc_api.h @@ -86,6 +86,8 @@ typedef void (*HTC_EP_RECV_REFILL)(void *, HTC_ENDPOINT_ID Endpoint); * Other OSes require a "per-packet" indication_RAW_STREAM_NUM_MAX for each completed TX packet, this * closed loop mechanism will prevent the network stack from overunning the NIC */ typedef void (*HTC_EP_SEND_QUEUE_FULL)(void *, HTC_ENDPOINT_ID Endpoint); +/* Optional per service connection callback when a send queue is available for receive new packet. */ +typedef void (*HTC_EP_SEND_QUEUE_AVAIL)(void *, HTC_ENDPOINT_ID Endpoint); typedef struct _HTC_EP_CALLBACKS { void *pContext; /* context for each callback */ @@ -93,6 +95,7 @@ typedef struct _HTC_EP_CALLBACKS { HTC_EP_RECV_PKT EpRecv; /* receive callback for connected endpoint */ HTC_EP_RECV_REFILL EpRecvRefill; /* OPTIONAL receive re-fill callback for connected endpoint */ HTC_EP_SEND_QUEUE_FULL EpSendFull; /* OPTIONAL send full callback */ + HTC_EP_SEND_QUEUE_AVAIL EpSendAvail; /* OPTIONAL send available callback */ } HTC_EP_CALLBACKS; /* service connection information */ diff --git a/drivers/input/keyboard/neo1973kbd.c b/drivers/input/keyboard/neo1973kbd.c index 56d3a689a4a..a95dd5806d2 100644 --- a/drivers/input/keyboard/neo1973kbd.c +++ b/drivers/input/keyboard/neo1973kbd.c @@ -368,8 +368,7 @@ static int neo1973kbd_probe(struct platform_device *pdev) goto out_device_create_file; /* register GPIO IRQs */ - - for(n = 0; n < ARRAY_SIZE(keys); n++) { + for(n = 0; n < min(pdev->num_resources, ARRAY_SIZE(keys)); n++) { if (!pdev->resource[0].start) continue; diff --git a/drivers/leds/leds-neo1973-vibrator.c b/drivers/leds/leds-neo1973-vibrator.c index e25ca4830bc..8bfb1179d03 100644 --- a/drivers/leds/leds-neo1973-vibrator.c +++ b/drivers/leds/leds-neo1973-vibrator.c @@ -129,7 +129,8 @@ static int neo1973_vib_init_hw(struct neo1973_vib_priv *vp) static int neo1973_vib_suspend(struct platform_device *dev, pm_message_t state) { led_classdev_suspend(&neo1973_vib_led.cdev); - neo1973_vib_priv.pdata->disable_fiq(); + if (neo1973_vib_priv.pdata) + neo1973_vib_priv.pdata->disable_fiq(); return 0; } @@ -141,7 +142,8 @@ static int neo1973_vib_resume(struct platform_device *dev) neo1973_vib_init_hw(vp); led_classdev_resume(&neo1973_vib_led.cdev); - neo1973_vib_priv.pdata->enable_fiq(); + if (neo1973_vib_priv.pdata) + neo1973_vib_priv.pdata->enable_fiq(); return 0; } diff --git a/drivers/mfd/glamo/Kconfig b/drivers/mfd/glamo/Kconfig index 4410d1e3245..eaa415df890 100644 --- a/drivers/mfd/glamo/Kconfig +++ b/drivers/mfd/glamo/Kconfig @@ -22,6 +22,16 @@ config MFD_GLAMO_FB If unsure, say N. +config MFD_GLAMO_FB_XGLAMO_WORKAROUND + bool "Smedia Glamo 336x/337x Xglamo rotation workaround" + depends on MFD_GLAMO_FB + help + This is a workaround for a Xglamo bug. This should be fixed + in Xglamo and not in kernel space. + + If unsure, say N. + + config MFD_GLAMO_SPI_GPIO tristate "Glamo GPIO SPI bitbang support" depends on MFD_GLAMO @@ -45,6 +55,7 @@ config MFD_GLAMO_MCI neo1973 GTA-02. If unsure, say N. + config MFD_GLAMO_DRM tristate "Glamo DRM support" depends on MFD_GLAMO && DRM @@ -53,4 +64,3 @@ config MFD_GLAMO_DRM used in Openmoko neo1973 GTA-02. If unsure, say N. - diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c index 77725a370e9..589b924b6bf 100644 --- a/drivers/mfd/glamo/glamo-fb.c +++ b/drivers/mfd/glamo/glamo-fb.c @@ -37,9 +37,9 @@ #include <linux/platform_device.h> #include <linux/clk.h> #include <linux/spinlock.h> +#include <linux/io.h> +#include <linux/uaccess.h> -#include <asm/io.h> -#include <asm/uaccess.h> #include <asm/div64.h> #ifdef CONFIG_PM @@ -76,6 +76,7 @@ struct glamofb_handle { u_int32_t pseudo_pal[16]; spinlock_t lock_cmd; int angle; /* Current rotation angle */ + int blank_mode; }; /* 'sibling' spi device for lcm init */ @@ -89,7 +90,7 @@ static int reg_read(struct glamofb_handle *glamo, { int i = 0; - for (i = 0; i != 2; i ++) + for (i = 0; i != 2; i++) nop(); return readw(glamo->base + reg); @@ -100,7 +101,7 @@ static void reg_write(struct glamofb_handle *glamo, { int i = 0; - for (i = 0; i != 2; i ++) + for (i = 0; i != 2; i++) nop(); writew(val, glamo->base + reg); @@ -141,7 +142,8 @@ static int glamofb_run_script(struct glamofb_handle *glamo, int i; if (glamo->mach_info->glamo->suspending) { - dev_err(&glamo->mach_info->glamo->pdev->dev, "IGNORING glamofb_run_script while " + dev_err(&glamo->mach_info->glamo->pdev->dev, + "IGNORING glamofb_run_script while " "suspended\n"); return -EBUSY; } @@ -166,7 +168,8 @@ static int glamofb_check_var(struct fb_var_screeninfo *var, struct glamofb_handle *glamo = info->par; if (glamo->mach_info->glamo->suspending) { - dev_err(&glamo->mach_info->glamo->pdev->dev, "IGNORING glamofb_check_var while " + dev_err(&glamo->mach_info->glamo->pdev->dev, + "IGNORING glamofb_check_var while " "suspended\n"); return -EBUSY; } @@ -256,6 +259,7 @@ static void reg_set_bit_mask(struct glamofb_handle *glamo, #define GLAMO_LCD_HV_RETR_DISP_START_MASK 0x03FF #define GLAMO_LCD_HV_RETR_DISP_END_MASK 0x03FF +enum orientation {ORIENTATION_PORTRAIT, ORIENTATION_LANDSCAPE}; /* the caller has to enxure lock_cmd is held and we are in cmd mode */ static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation) @@ -263,32 +267,33 @@ static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation) int glamo_rot; if (glamo->mach_info->glamo->suspending) { - dev_err(&glamo->mach_info->glamo->pdev->dev, "IGNORING rotate_lcd while " + dev_err(&glamo->mach_info->glamo->pdev->dev, + "IGNORING rotate_lcd while " "suspended\n"); return; } switch (rotation) { - case FB_ROTATE_UR: - glamo_rot = GLAMO_LCD_ROT_MODE_0; - glamo->angle = 0; - break; - case FB_ROTATE_CW: - glamo_rot = GLAMO_LCD_ROT_MODE_90; - glamo->angle = 90; - break; - case FB_ROTATE_UD: - glamo_rot = GLAMO_LCD_ROT_MODE_180; - glamo->angle = 180; - break; - case FB_ROTATE_CCW: - glamo_rot = GLAMO_LCD_ROT_MODE_270; - glamo->angle = 270; - break; - default: - glamo->angle = 0; - glamo_rot = GLAMO_LCD_ROT_MODE_0; - break; + case FB_ROTATE_UR: + glamo_rot = GLAMO_LCD_ROT_MODE_0; + glamo->angle = 0; + break; + case FB_ROTATE_CW: + glamo_rot = GLAMO_LCD_ROT_MODE_90; + glamo->angle = 90; + break; + case FB_ROTATE_UD: + glamo_rot = GLAMO_LCD_ROT_MODE_180; + glamo->angle = 180; + break; + case FB_ROTATE_CCW: + glamo_rot = GLAMO_LCD_ROT_MODE_270; + glamo->angle = 270; + break; + default: + glamo->angle = 0; + glamo_rot = GLAMO_LCD_ROT_MODE_0; + break; } reg_set_bit_mask(glamo, @@ -298,43 +303,90 @@ static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation) reg_set_bit_mask(glamo, GLAMO_REG_LCD_MODE1, GLAMO_LCD_MODE1_ROTATE_EN, - (glamo_rot != GLAMO_LCD_ROT_MODE_0)? + (glamo_rot != GLAMO_LCD_ROT_MODE_0) ? GLAMO_LCD_MODE1_ROTATE_EN : 0); } -static void glamofb_update_lcd_controller(struct glamofb_handle *glamo, - struct fb_var_screeninfo *var) +static enum orientation get_orientation(struct fb_var_screeninfo *var) { - int sync, bp, disp, fp, total, pitch; - unsigned long flags; - int width, height; + if (var->xres <= var->yres) + return ORIENTATION_PORTRAIT; - if (!glamo || !var) - return; + return ORIENTATION_LANDSCAPE; +} - if (glamo->mach_info->glamo->suspending) { - dev_err(&glamo->mach_info->glamo->pdev->dev, "IGNORING glamofb_update_lcd_controller while " - "suspended\n"); - return; +static int will_orientation_change(struct fb_var_screeninfo *var) +{ + enum orientation orient = get_orientation(var); + + switch (orient) { + case ORIENTATION_LANDSCAPE: + if (var->rotate == FB_ROTATE_UR || var->rotate == FB_ROTATE_UD) + return 1; + break; + case ORIENTATION_PORTRAIT: + if (var->rotate == FB_ROTATE_CW || var->rotate == FB_ROTATE_CCW) + return 1; + break; } + return 0; +} - dev_dbg(&glamo->mach_info->glamo->pdev->dev, - "glamofb_update_lcd_controller spin_lock_irqsave\n"); - spin_lock_irqsave(&glamo->lock_cmd, flags); +#ifdef CONFIG_MFD_GLAMO_FB_XGLAMO_WORKAROUND - if (glamofb_cmd_mode(glamo, 1)) - goto out_unlock; +/* + * See https://docs.openmoko.org/trac/ticket/2255 + * We have a hack for some Xglamo bugs in kernel code. + * If someone fixes xglamo we can remove this hack. + * We might make xglamo_hack_enabled 0 by default in the future. + */ - if (var->pixclock) - glamo_engine_reclock(glamo->mach_info->glamo, - GLAMO_ENGINE_LCD, - var->pixclock); +static unsigned xglamo_hack_enabled = 1; + +static ssize_t xglamo_hack_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", xglamo_hack_enabled); +} + +static ssize_t xglamo_hack_write(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + unsigned long val; + + if (!strict_strtoul(buf, 10, &val)) + xglamo_hack_enabled = !!val; + + return count; +} + +static DEVICE_ATTR(xglamo_hack, S_IWUSR | S_IRUGO, xglamo_hack_read, + xglamo_hack_write); + +static struct attribute *glamo_fb_sysfs_entries[] = { + &dev_attr_xglamo_hack.attr, + NULL +}; + +static struct attribute_group glamo_fb_attr_group = { + .name = NULL, + .attrs = glamo_fb_sysfs_entries, +}; + +/* This function implements the actual Xglamo hack. */ + +static void glamofb_update_lcd_controller_hack(struct glamofb_handle *glamo, + struct fb_var_screeninfo *var, + int *xres, int *yres, int *pitch) +{ + int width, height; if (glamo->angle == 90 || glamo->angle == 270) { - /* + /* * But if we are going back to portrait mode from here, - * we get inverted values from Xglamo - */ + * we get inverted values from Xglamo + */ if (!(var->rotate == FB_ROTATE_UR || var->rotate == FB_ROTATE_UD)) { width = var->yres; @@ -354,28 +406,85 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo, /* We don't need to set xres and yres in this particular case * because Xglamo does it for us */ if (!(glamo->angle == 90 || glamo->angle == 270)) { - var->xres = width;var->yres = height; + var->xres = width; + var->yres = height; } var->xres_virtual = width; var->yres_virtual = height * 2; - pitch = width * var->bits_per_pixel / 8; + *pitch = width * var->bits_per_pixel / 8; } else { var->xres = height; var->yres = width; var->xres_virtual = height * 2; var->yres_virtual = width; - pitch = height * var->bits_per_pixel / 8; + *pitch = height * var->bits_per_pixel / 8; + } + + *xres = width; + *yres = height; +} +#else +#define xglamo_hack_enabled 0 +static void glamofb_update_lcd_controller_hack(struct glamofb_handle *glamo, + struct fb_var_screeninfo *var, + int *xres, int *yres, int *pitch) +{ +} +#endif + +static void glamofb_update_lcd_controller(struct glamofb_handle *glamo, + struct fb_var_screeninfo *var) +{ + int sync, bp, disp, fp, total, xres, yres, pitch; + int uninitialized_var(orientation_changing); + unsigned long flags; + + if (!glamo || !var) + return; + + if (glamo->mach_info->glamo->suspending) { + dev_err(&glamo->mach_info->glamo->pdev->dev, + "IGNORING glamofb_update_lcd_controller while " + "suspended\n"); + return; + } + + dev_dbg(&glamo->mach_info->glamo->pdev->dev, + "glamofb_update_lcd_controller spin_lock_irqsave\n"); + spin_lock_irqsave(&glamo->lock_cmd, flags); + + if (glamofb_cmd_mode(glamo, 1)) + goto out_unlock; + + if (var->pixclock) + glamo_engine_reclock(glamo->mach_info->glamo, + GLAMO_ENGINE_LCD, + var->pixclock); + + if (xglamo_hack_enabled) { + glamofb_update_lcd_controller_hack(glamo, var, &xres, &yres, + &pitch); + } else { + xres = var->xres; + yres = var->yres; + + orientation_changing = will_orientation_change(var); + /* Adjust the pitch according to new orientation to come. */ + if (orientation_changing) + pitch = var->yres * var->bits_per_pixel / 8; + else + pitch = var->xres * var->bits_per_pixel / 8; } reg_set_bit_mask(glamo, GLAMO_REG_LCD_WIDTH, GLAMO_LCD_WIDTH_MASK, - width); + xres); reg_set_bit_mask(glamo, GLAMO_REG_LCD_HEIGHT, GLAMO_LCD_HEIGHT_MASK, - height); + yres); reg_set_bit_mask(glamo, GLAMO_REG_LCD_PITCH, GLAMO_LCD_PITCH_MASK, @@ -384,11 +493,26 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo, /* honour the rotation request */ __rotate_lcd(glamo, var->rotate); + if (!xglamo_hack_enabled) { + /* update the reported geometry of the framebuffer. */ + if (orientation_changing) { + var->xres_virtual = yres; + var->xres = yres; + var->xres_virtual *= 2; + var->yres_virtual = xres; + var->yres = xres; + } else { + var->xres_virtual = xres; + var->yres_virtual = yres; + var->yres_virtual *= 2; + } + } + /* update scannout timings */ sync = 0; bp = sync + var->hsync_len; disp = bp + var->left_margin; - fp = disp + width; + fp = disp + xres; total = fp + var->right_margin; reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_TOTAL, @@ -405,7 +529,7 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo, sync = 0; bp = sync + var->vsync_len; disp = bp + var->upper_margin; - fp = disp + height; + fp = disp + yres; total = fp + var->lower_margin; reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_TOTAL, @@ -427,7 +551,8 @@ out_unlock: spin_unlock_irqrestore(&glamo->lock_cmd, flags); } -static int glamofb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) +static int glamofb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *info) { struct glamofb_handle *glamo = info->par; u_int16_t page = var->yoffset / glamo->mach_info->yres.defval; @@ -442,7 +567,8 @@ static int glamofb_set_par(struct fb_info *info) struct fb_var_screeninfo *var = &info->var; if (glamo->mach_info->glamo->suspending) { - dev_err(&glamo->mach_info->glamo->pdev->dev, "IGNORING glamofb_set_par while " + dev_err(&glamo->mach_info->glamo->pdev->dev, + "IGNORING glamofb_set_par while " "suspended\n"); return -EBUSY; } @@ -488,17 +614,29 @@ static int glamofb_blank(int blank_mode, struct fb_info *info) * we should already switch off pixel clock here */ break; case FB_BLANK_POWERDOWN: + /* Simulating FB_BLANK_NORMAL allow turning off backlight */ + if (gfb->blank_mode != FB_BLANK_NORMAL) + notify_blank(info, FB_BLANK_NORMAL); + + /* LCM need notification before pixel clock is stopped */ + notify_blank(info, blank_mode); + /* disable the pixel clock */ glamo_engine_clkreg_set(gcore, GLAMO_ENGINE_LCD, GLAMO_CLOCK_LCD_EN_DCLK, 0); + gfb->blank_mode = blank_mode; break; case FB_BLANK_UNBLANK: case FB_BLANK_NORMAL: - /* enable the pixel clock */ - glamo_engine_clkreg_set(gcore, GLAMO_ENGINE_LCD, + /* enable the pixel clock if off */ + if (gfb->blank_mode == FB_BLANK_POWERDOWN) + glamo_engine_clkreg_set(gcore, + GLAMO_ENGINE_LCD, GLAMO_CLOCK_LCD_EN_DCLK, GLAMO_CLOCK_LCD_EN_DCLK); + notify_blank(info, blank_mode); + gfb->blank_mode = blank_mode; break; } @@ -524,7 +662,8 @@ static int glamofb_setcolreg(unsigned regno, unsigned int val; if (glamo->mach_info->glamo->suspending) { - dev_err(&glamo->mach_info->glamo->pdev->dev, "IGNORING glamofb_set_par while " + dev_err(&glamo->mach_info->glamo->pdev->dev, + "IGNORING glamofb_set_par while " "suspended\n"); return -EBUSY; } @@ -698,7 +837,8 @@ int glamofb_cmd_mode(struct glamofb_handle *gfb, int on) int timeout = 2000000; if (gfb->mach_info->glamo->suspending) { - dev_err(&gfb->mach_info->glamo->pdev->dev, "IGNORING glamofb_cmd_mode while " + dev_err(&gfb->mach_info->glamo->pdev->dev, + "IGNORING glamofb_cmd_mode while " "suspended\n"); return -EBUSY; } @@ -706,7 +846,7 @@ int glamofb_cmd_mode(struct glamofb_handle *gfb, int on) dev_dbg(gfb->dev, "glamofb_cmd_mode(gfb=%p, on=%d)\n", gfb, on); if (on) { dev_dbg(gfb->dev, "%s: waiting for cmdq empty: ", - __FUNCTION__); + __func__); while ((!glamofb_cmdq_empty(gfb)) && (timeout--)) /* yield() */; if (timeout < 0) { @@ -761,12 +901,13 @@ int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val) int timeout = 200000; if (gfb->mach_info->glamo->suspending) { - dev_err(&gfb->mach_info->glamo->pdev->dev, "IGNORING glamofb_cmd_write while " + dev_err(&gfb->mach_info->glamo->pdev->dev, + "IGNORING glamofb_cmd_write while " "suspended\n"); return -EBUSY; } - dev_dbg(gfb->dev, "%s: waiting for cmdq empty\n", __FUNCTION__); + dev_dbg(gfb->dev, "%s: waiting for cmdq empty\n", __func__); while ((!glamofb_cmdq_empty(gfb)) && (timeout--)) yield(); if (timeout < 0) { @@ -828,6 +969,7 @@ static int __init glamofb_probe(struct platform_device *pdev) glamofb->dev = &pdev->dev; glamofb->angle = 0; + glamofb->blank_mode = FB_BLANK_POWERDOWN; strcpy(fbinfo->fix.id, "SMedia Glamo"); @@ -934,6 +1076,15 @@ static int __init glamofb_probe(struct platform_device *pdev) glamofb_cursor_onoff(glamofb, 1); #endif +#ifdef CONFIG_MFD_GLAMO_FB_XGLAMO_WORKAROUND + /* sysfs */ + rc = sysfs_create_group(&pdev->dev.kobj, &glamo_fb_attr_group); + if (rc < 0) { + dev_err(&pdev->dev, "cannot create sysfs group\n"); + goto out_unmap_fb; + } +#endif + rc = register_framebuffer(fbinfo); if (rc < 0) { dev_err(&pdev->dev, "failed to register framebuffer\n"); @@ -984,38 +1135,35 @@ static int glamofb_suspend(struct platform_device *pdev, pm_message_t state) struct glamofb_handle *gfb = platform_get_drvdata(pdev); /* we need to stop anything touching our framebuffer */ -// fb_blank(gfb->fb, FB_BLANK_NORMAL); fb_set_suspend(gfb->fb, 1); /* seriously -- nobody is allowed to touch glamo memory when we * are suspended or we lock on nWAIT */ -// iounmap(gfb->fb->screen_base); + /* iounmap(gfb->fb->screen_base); */ return 0; } static int glamofb_resume(struct platform_device *pdev) { - struct glamofb_handle *glamofb = platform_get_drvdata(pdev); + struct glamofb_handle *gfb = platform_get_drvdata(pdev); struct glamofb_platform_data *mach_info = pdev->dev.platform_data; /* OK let's allow framebuffer ops again */ -// gfb->fb->screen_base = ioremap(gfb->fb_res->start, -// RESSIZE(gfb->fb_res)); + /* gfb->fb->screen_base = ioremap(gfb->fb_res->start, + RESSIZE(gfb->fb_res)); */ glamo_engine_enable(mach_info->glamo, GLAMO_ENGINE_LCD); glamo_engine_reset(mach_info->glamo, GLAMO_ENGINE_LCD); printk(KERN_ERR"spin_lock_init\n"); - spin_lock_init(&glamofb->lock_cmd); - glamofb_init_regs(glamofb); + spin_lock_init(&gfb->lock_cmd); + glamofb_init_regs(gfb); #ifdef CONFIG_MFD_GLAMO_HWACCEL - glamofb_cursor_onoff(glamofb, 1); + glamofb_cursor_onoff(gfb, 1); #endif - - fb_set_suspend(glamofb->fb, 0); -// fb_blank(gfb->fb, FB_BLANK_UNBLANK); + fb_set_suspend(gfb->fb, 0); return 0; } diff --git a/drivers/mfd/pcf50606-adc.c b/drivers/mfd/pcf50606-adc.c index fe0336b9753..38f5b5c0593 100644 --- a/drivers/mfd/pcf50606-adc.c +++ b/drivers/mfd/pcf50606-adc.c @@ -175,7 +175,7 @@ static int adc_result(struct pcf50606 *pcf) u16 ret = (pcf50606_reg_read(pcf, PCF50606_REG_ADCS1) << 2) | (pcf50606_reg_read(pcf, PCF50606_REG_ADCS2) & 0x03); - dev_info(pcf->dev, "adc result = %d\n", ret); + dev_dbg(pcf->dev, "adc result = %d\n", ret); return ret; } diff --git a/drivers/mfd/pcf50606-core.c b/drivers/mfd/pcf50606-core.c index 9d0bdae0cb5..7c4fb42b460 100644 --- a/drivers/mfd/pcf50606-core.c +++ b/drivers/mfd/pcf50606-core.c @@ -349,7 +349,7 @@ static void pcf50606_irq_worker(struct work_struct *work) pcf_int[1] &= ~(1 << PCF50606_INT2_CHGINS); } - dev_info(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x\n", + dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x\n", pcf_int[0], pcf_int[1], pcf_int[2]); /* Some revisions of the chip don't have a 8s standby mode on diff --git a/drivers/power/bq27000_battery.c b/drivers/power/bq27000_battery.c index bc3856e5755..9f0f1a96720 100644 --- a/drivers/power/bq27000_battery.c +++ b/drivers/power/bq27000_battery.c @@ -173,6 +173,7 @@ static void bq27000_battery_external_power_changed(struct power_supply *psy) struct bq27000_device_info *di = container_of(psy, struct bq27000_device_info, bat); dev_dbg(di->dev, "%s\n", __FUNCTION__); + schedule_delayed_work(&di->work, 0); } static int bq27000_battery_get_property(struct power_supply *psy, diff --git a/drivers/power/gta01_battery.c b/drivers/power/gta01_battery.c index 126b1721f8d..909f7fe16d9 100644 --- a/drivers/power/gta01_battery.c +++ b/drivers/power/gta01_battery.c @@ -44,7 +44,6 @@ static int gta01_bat_get_property(struct power_supply *psy, val->intval = bat->pdata->get_current(); break; default: - printk(KERN_ERR "Unknown property benig asked for\n"); return -EINVAL; } diff --git a/drivers/rtc/rtc-pcf50606.c b/drivers/rtc/rtc-pcf50606.c index e059093d908..434cfc1dca4 100644 --- a/drivers/rtc/rtc-pcf50606.c +++ b/drivers/rtc/rtc-pcf50606.c @@ -70,7 +70,7 @@ static void pcf2rtc_time(struct rtc_time *rtc, struct pcf50606_time *pcf) rtc->tm_hour = bcd2bin(pcf->time[PCF50606_TI_HOUR]); rtc->tm_wday = bcd2bin(pcf->time[PCF50606_TI_WKDAY]); rtc->tm_mday = bcd2bin(pcf->time[PCF50606_TI_DAY]); - rtc->tm_mon = bcd2bin(pcf->time[PCF50606_TI_MONTH]); + rtc->tm_mon = bcd2bin(pcf->time[PCF50606_TI_MONTH]) - 1; rtc->tm_year = bcd2bin(pcf->time[PCF50606_TI_YEAR]) + 100; } @@ -81,7 +81,7 @@ static void rtc2pcf_time(struct pcf50606_time *pcf, struct rtc_time *rtc) pcf->time[PCF50606_TI_HOUR] = bin2bcd(rtc->tm_hour); pcf->time[PCF50606_TI_WKDAY] = bin2bcd(rtc->tm_wday); pcf->time[PCF50606_TI_DAY] = bin2bcd(rtc->tm_mday); - pcf->time[PCF50606_TI_MONTH] = bin2bcd(rtc->tm_mon); + pcf->time[PCF50606_TI_MONTH] = bin2bcd(rtc->tm_mon + 1); pcf->time[PCF50606_TI_YEAR] = bin2bcd(rtc->tm_year % 100); } diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 86d9775e071..b14f3808adc 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -18,7 +18,6 @@ * This file is licenced under the GPL. */ -#define DEBUG 2 #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/pci.h> diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 5d8d556d92c..cdbd3f2fd32 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -21,10 +21,9 @@ #include <linux/platform_device.h> #include <linux/clk.h> - -//#include <mach/hardware.h> +#include <mach/hardware.h> +#include <mach/regs-gpio.h> #include <plat/usb-control.h> -//#include <mach/regs-gpio.h> #define valid_port(idx) ((idx) == 1 || (idx) == 2) @@ -59,9 +58,8 @@ static void s3c2410_start_hc(struct platform_device *dev, struct usb_hcd *hcd) info->hcd = hcd; info->report_oc = s3c2410_hcd_oc; - if (info->enable_oc != NULL) { + if (info->enable_oc != NULL) (info->enable_oc)(info, 1); - } } } @@ -75,9 +73,8 @@ static void s3c2410_stop_hc(struct platform_device *dev) info->report_oc = NULL; info->hcd = NULL; - if (info->enable_oc != NULL) { + if (info->enable_oc != NULL) (info->enable_oc)(info, 0); - } } clk_disable(clk); @@ -91,14 +88,14 @@ static void s3c2410_stop_hc(struct platform_device *dev) */ static int -ohci_s3c2410_hub_status_data (struct usb_hcd *hcd, char *buf) +ohci_s3c2410_hub_status_data(struct usb_hcd *hcd, char *buf) { struct s3c2410_hcd_info *info = to_s3c2410_info(hcd); struct s3c2410_hcd_port *port; int orig; int portno; - orig = ohci_hub_status_data (hcd, buf); + orig = ohci_hub_status_data(hcd, buf); if (info == NULL) return orig; @@ -148,7 +145,7 @@ static void s3c2410_usb_set_power(struct s3c2410_hcd_info *info, * request. */ -static int ohci_s3c2410_hub_control ( +static int ohci_s3c2410_hub_control( struct usb_hcd *hcd, u16 typeReq, u16 wValue, @@ -202,9 +199,8 @@ static int ohci_s3c2410_hub_control ( dev_dbg(hcd->self.controller, "ClearPortFeature: OVER_CURRENT\n"); - if (valid_port(wIndex)) { + if (valid_port(wIndex)) info->port[wIndex-1].oc_status = 0; - } goto out; @@ -245,28 +241,28 @@ static int ohci_s3c2410_hub_control ( desc->wHubCharacteristics |= cpu_to_le16(0x0001); if (info->enable_oc) { - desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_OCPM); - desc->wHubCharacteristics |= cpu_to_le16(0x0008|0x0001); + desc->wHubCharacteristics &= + ~cpu_to_le16(HUB_CHAR_OCPM); + desc->wHubCharacteristics |= + cpu_to_le16(0x0008|0x0001); } - dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n", + dev_dbg(hcd->self.controller, + "wHubCharacteristics after 0x%04x\n", desc->wHubCharacteristics); return ret; case GetPortStatus: /* check port status */ - dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex); if (valid_port(wIndex)) { - if (info->port[wIndex-1].oc_changed) { + if (info->port[wIndex-1].oc_changed) *data |= cpu_to_le32(RH_PS_OCIC); - } - if (info->port[wIndex-1].oc_status) { + if (info->port[wIndex-1].oc_status) *data |= cpu_to_le32(RH_PS_POCI); - } } } @@ -309,7 +305,6 @@ static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc) local_irq_restore(flags); } -#if 0 /* switching of USB pads */ static ssize_t show_usb_mode(struct device *dev, struct device_attribute *attr, char *buf) @@ -324,7 +319,7 @@ static ssize_t set_usb_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { if (!strncmp(buf, "host", 4)) { - printk("s3c2410: changing usb to host\n"); + printk(KERN_WARNING "s3c2410: changing usb to host\n"); s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST, S3C2410_MISCCR_USBHOST); /* FIXME: @@ -333,11 +328,11 @@ static ssize_t set_usb_mode(struct device *dev, struct device_attribute *attr, */ s3c2410_gpio_setpin(S3C2410_GPB9, 0); } else if (!strncmp(buf, "device", 6)) { - printk("s3c2410: changing usb to device\n"); + printk(KERN_WARNING "s3c2410: changing usb to device\n"); s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST, 0); s3c2410_gpio_setpin(S3C2410_GPB9, 1); } else { - printk("s3c2410: unknown mode\n"); + printk(KERN_WARNING "s3c2410: unknown mode\n"); return -EINVAL; } @@ -345,7 +340,6 @@ static ssize_t set_usb_mode(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(usb_mode, S_IRUGO | S_IWUSR, show_usb_mode, set_usb_mode); -#endif /* may be called without controller electrically present */ /* may be called with controller, bus, and devices active */ @@ -362,9 +356,9 @@ static DEVICE_ATTR(usb_mode, S_IRUGO | S_IWUSR, show_usb_mode, set_usb_mode); */ static void -usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) +usb_hcd_s3c2410_remove(struct usb_hcd *hcd, struct platform_device *dev) { - //device_remove_file(&dev->dev, &dev_attr_usb_mode); + device_remove_file(&dev->dev, &dev_attr_usb_mode); usb_remove_hcd(hcd); s3c2410_stop_hc(dev); iounmap(hcd->regs); @@ -381,8 +375,8 @@ usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) * through the hotplug entry's driver_data. * */ -static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, - struct platform_device *dev) +static int usb_hcd_s3c2410_probe(const struct hc_driver *driver, + struct platform_device *dev) { struct usb_hcd *hcd = NULL; int retval; @@ -432,16 +426,16 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, if (retval != 0) goto err_ioremap; -// retval = device_create_file(&dev->dev, &dev_attr_usb_mode); -// if (retval != 0) -// goto err_hcd; + retval = device_create_file(&dev->dev, &dev_attr_usb_mode); + if (retval != 0) + goto err_hcd; return 0; -// err_hcd: -// usb_remove_hcd(hcd); +err_hcd: + usb_remove_hcd(hcd); - err_ioremap: +err_ioremap: s3c2410_stop_hc(dev); iounmap(hcd->regs); clk_put(usb_clk); @@ -460,17 +454,19 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, /*-------------------------------------------------------------------------*/ static int -ohci_s3c2410_start (struct usb_hcd *hcd) +ohci_s3c2410_start(struct usb_hcd *hcd) { - struct ohci_hcd *ohci = hcd_to_ohci (hcd); + struct ohci_hcd *ohci = hcd_to_ohci(hcd); int ret; - if ((ret = ohci_init(ohci)) < 0) + ret = ohci_init(ohci); + if (ret < 0) return ret; - if ((ret = ohci_run (ohci)) < 0) { - err ("can't start %s", hcd->self.bus_name); - ohci_stop (hcd); + ret = ohci_run(ohci); + if (ret < 0) { + err("can't start %s", hcd->self.bus_name); + ohci_stop(hcd); return ret; } diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 4cefce8a910..208da5af5f2 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -3130,17 +3130,13 @@ static void fbcon_get_requirement(struct fb_info *info, static int fbcon_event_notify(struct notifier_block *self, unsigned long action, void *data) { - struct fb_event *event; - struct fb_info *info; + struct fb_event *event = data; + struct fb_info *info = event->info; struct fb_videomode *mode; struct fb_con2fbmap *con2fb; struct fb_blit_caps *caps; int ret = 0; - printk(KERN_INFO "fbcon_event_notify action=%ld, data=%p\n", action, data); - - event = data; - info = event->info; /* * ignore all events except driver registration and deregistration * if fbcon is not active diff --git a/drivers/video/display/jbt6k74.c b/drivers/video/display/jbt6k74.c index 9add1c6bf8a..5d7a6519de9 100644 --- a/drivers/video/display/jbt6k74.c +++ b/drivers/video/display/jbt6k74.c @@ -31,6 +31,7 @@ #include <linux/delay.h> #include <linux/jbt6k74.h> #include <linux/fb.h> +#include <linux/time.h> enum jbt_register { JBT_REG_SLEEP_IN = 0x10, @@ -117,12 +118,18 @@ struct jbt_info { struct notifier_block fb_notif; u16 tx_buf[8]; u16 reg_cache[0xEE]; - int have_resumed; + struct timespec last_sleep; }; #define JBT_COMMAND 0x000 #define JBT_DATA 0x100 +static inline unsigned int timespec_sub_ms(struct timespec lhs, + struct timespec rhs) +{ + struct timespec ts = timespec_sub(lhs, rhs); + return (ts.tv_sec * MSEC_PER_SEC) + (ts.tv_nsec / NSEC_PER_MSEC); +} static int jbt_reg_write_nodata(struct jbt_info *jbt, u8 reg) { @@ -179,7 +186,7 @@ static int jbt_init_regs(struct jbt_info *jbt) { int rc; - dev_dbg(&jbt->spi_dev->dev, "entering %cVGA mode\n", + dev_dbg(&jbt->spi_dev->dev, "entering %cVGA mode\n", jbt->normal_state == JBT_STATE_QVGA_NORMAL ? 'Q' : ' '); rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE1, 0x01); @@ -268,36 +275,25 @@ static int sleep_to_normal(struct jbt_info *jbt) { int rc; - /* RGB I/F on, RAM wirte off, QVGA through, SIGCON enable */ - rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x80); - - /* Quad mode off */ - rc |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x00); - - /* AVDD on, XVDD on */ - rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x16); - - /* Output control */ - rc |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0xfff9); - - /* Turn on display */ - rc |= jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_ON); - - /* Sleep mode off */ - rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_OUT); - - return rc ? -EIO : 0; -} + /* Make sure we are 120 ms after SLEEP_OUT */ + unsigned int sleep_time = timespec_sub_ms(current_kernel_time(), + jbt->last_sleep); + if (sleep_time < 120) + mdelay(120 - sleep_time); -static int sleep_to_qvga_normal(struct jbt_info *jbt) -{ - int rc; + if (jbt->normal_state == JBT_STATE_NORMAL) { + /* RGB I/F on, RAM wirte off, QVGA through, SIGCON enable */ + rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x80); - /* RGB I/F on, RAM wirte off, QVGA through, SIGCON enable */ - rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x81); + /* Quad mode off */ + rc |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x00); + } else { + /* RGB I/F on, RAM wirte off, QVGA through, SIGCON enable */ + rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x81); - /* Quad mode on */ - rc |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x22); + /* Quad mode on */ + rc |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x22); + } /* AVDD on, XVDD on */ rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x16); @@ -310,6 +306,10 @@ static int sleep_to_qvga_normal(struct jbt_info *jbt) /* Sleep mode off */ rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_OUT); + jbt->last_sleep = current_kernel_time(); + + /* Allow the booster and display controller to restart stably */ + mdelay(5); return rc ? -EIO : 0; } @@ -318,9 +318,19 @@ static int normal_to_sleep(struct jbt_info *jbt) { int rc; + /* Make sure we are 120 ms after SLEEP_OUT */ + unsigned int sleep_time = timespec_sub_ms(current_kernel_time(), + jbt->last_sleep); + if (sleep_time < 120) + mdelay(120 - sleep_time); + rc = jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_OFF); rc |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0x8002); rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_IN); + jbt->last_sleep = current_kernel_time(); + + /* Allow the internal circuits to stop automatically */ + mdelay(5); return rc ? -EIO : 0; } @@ -335,8 +345,9 @@ int jbt6k74_enter_state(struct jbt_info *jbt, enum jbt_state new_state) { int rc = -EINVAL; - dev_dbg(&jbt->spi_dev->dev, "entering (old_state=%s, " - "new_state=%s)\n", jbt_state_names[jbt->state], jbt_state_names[new_state]); + dev_dbg(&jbt->spi_dev->dev, "entering (old_state=%s, new_state=%s)\n", + jbt_state_names[jbt->state], + jbt_state_names[new_state]); mutex_lock(&jbt->lock); @@ -363,7 +374,7 @@ int jbt6k74_enter_state(struct jbt_info *jbt, enum jbt_state new_state) /* first transition into sleep */ rc = standby_to_sleep(jbt); /* then transition into normal */ - rc |= sleep_to_qvga_normal(jbt); + rc |= sleep_to_normal(jbt); break; } break; @@ -376,10 +387,8 @@ int jbt6k74_enter_state(struct jbt_info *jbt, enum jbt_state new_state) rc = sleep_to_standby(jbt); break; case JBT_STATE_NORMAL: - rc = sleep_to_normal(jbt); - break; case JBT_STATE_QVGA_NORMAL: - rc = sleep_to_qvga_normal(jbt); + rc = sleep_to_normal(jbt); break; } break; @@ -405,7 +414,7 @@ int jbt6k74_enter_state(struct jbt_info *jbt, enum jbt_state new_state) /* third transition into sleep */ rc |= standby_to_sleep(jbt); /* fourth transition into normal */ - rc |= sleep_to_qvga_normal(jbt); + rc |= sleep_to_normal(jbt); break; } break; @@ -436,12 +445,13 @@ int jbt6k74_enter_state(struct jbt_info *jbt, enum jbt_state new_state) } break; } - + if (rc == 0) jbt->state = new_state; else - dev_err(&jbt->spi_dev->dev, "Failed enter state '%s')\n", jbt_state_names[new_state]); - + dev_err(&jbt->spi_dev->dev, "Failed enter state '%s')\n", + jbt_state_names[new_state]); + mutex_unlock(&jbt->lock); return rc; @@ -513,7 +523,7 @@ static ssize_t gamma_write(struct device *dev, struct device_attribute *attr, int reg = reg_by_string(attr->attr.name); unsigned long val = simple_strtoul(buf, NULL, 10); - dev_info(dev, "**** jbt6k74 writing gama %lu\n", val & 0xff); + dev_info(dev, "writing gama %lu\n", val & 0xff); mutex_lock(&jbt->lock); jbt_reg_write(jbt, reg, val & 0xff); @@ -525,18 +535,27 @@ static ssize_t gamma_write(struct device *dev, struct device_attribute *attr, static ssize_t reset_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { + int rc; struct jbt_info *jbt = dev_get_drvdata(dev); - struct jbt6k74_platform_data *jbt6k74_pdata = jbt->spi_dev->dev.platform_data; + struct jbt6k74_platform_data *pdata = jbt->spi_dev->dev.platform_data; - dev_info(dev, "**** jbt6k74 reset\n"); + dev_info(dev, "reset\n"); - jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY); + mutex_lock(&jbt->lock); + + jbt->state = JBT_STATE_DEEP_STANDBY; /* hard reset the jbt6k74 */ - mutex_lock(&jbt->lock); - (jbt6k74_pdata->reset)(0, 0); + (pdata->reset)(0, 0); mdelay(1); - (jbt6k74_pdata->reset)(0, 1); + (pdata->reset)(0, 1); + mdelay(120); + + rc = jbt_reg_write_nodata(jbt, 0x01); + if (rc < 0) + dev_err(&jbt->spi_dev->dev, "cannot soft reset\n"); + mdelay(120); + mutex_unlock(&jbt->lock); jbt6k74_enter_state(jbt, jbt->normal_state); @@ -572,31 +591,30 @@ static int fb_notifier_callback(struct notifier_block *self, struct fb_event *evdata = data; int fb_blank; + jbt = container_of(self, struct jbt_info, fb_notif); + + dev_dbg(&jbt->spi_dev->dev, "event=%lu\n", event); + if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK) return 0; fb_blank = *(int *)evdata->data; - jbt = container_of(self, struct jbt_info, fb_notif); - switch (fb_blank) { case FB_BLANK_UNBLANK: - dev_info(&jbt->spi_dev->dev, "**** jbt6k74 unblank\n"); + dev_dbg(&jbt->spi_dev->dev, "unblank\n"); jbt6k74_enter_state(jbt, jbt->normal_state); break; case FB_BLANK_NORMAL: - dev_info(&jbt->spi_dev->dev, "**** jbt6k74 normal\n"); + dev_dbg(&jbt->spi_dev->dev, "blank\n"); break; case FB_BLANK_VSYNC_SUSPEND: - dev_info(&jbt->spi_dev->dev, "**** jbt6k74 vsync suspend\n"); + dev_dbg(&jbt->spi_dev->dev, "vsync suspend\n"); break; case FB_BLANK_HSYNC_SUSPEND: - dev_info(&jbt->spi_dev->dev, "**** jbt6k74 hsync suspend\n"); + dev_dbg(&jbt->spi_dev->dev, "hsync suspend\n"); break; case FB_BLANK_POWERDOWN: - dev_info(&jbt->spi_dev->dev, "**** jbt6k74 powerdown\n"); - /* FIXME DEEP STANDBY wihtout suspend causes WSOD at cold - * temperature on certain devices. */ - /*jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);*/ + dev_dbg(&jbt->spi_dev->dev, "powerdown\n"); jbt6k74_enter_state(jbt, JBT_STATE_SLEEP); break; } @@ -610,7 +628,7 @@ static int __devinit jbt_probe(struct spi_device *spi) { int rc; struct jbt_info *jbt; - struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data; + struct jbt6k74_platform_data *pdata = spi->dev.platform_data; /* the controller doesn't have a MISO pin; we can't do detection */ @@ -631,6 +649,7 @@ static int __devinit jbt_probe(struct spi_device *spi) jbt->spi_dev = spi; jbt->normal_state = JBT_STATE_NORMAL; jbt->state = JBT_STATE_DEEP_STANDBY; + jbt->last_sleep = current_kernel_time(); mutex_init(&jbt->lock); dev_set_drvdata(&spi->dev, jbt); @@ -654,8 +673,8 @@ static int __devinit jbt_probe(struct spi_device *spi) goto err_sysfs; } - if (jbt6k74_pdata->probe_completed) - (jbt6k74_pdata->probe_completed)(&spi->dev); + if (pdata->probe_completed) + (pdata->probe_completed)(&spi->dev); return 0; @@ -693,9 +712,7 @@ static int jbt_suspend(struct spi_device *spi, pm_message_t state) jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY); - jbt->have_resumed = 0; - - dev_info(&spi->dev, "**** jbt6k74 suspend end\n"); + dev_info(&spi->dev, "suspended\n"); return 0; } @@ -703,16 +720,14 @@ static int jbt_suspend(struct spi_device *spi, pm_message_t state) int jbt6k74_resume(struct spi_device *spi) { struct jbt_info *jbt = dev_get_drvdata(&spi->dev); - struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data; - - dev_info(&spi->dev, "**** jbt6k74 resume start\n"); + struct jbt6k74_platform_data *pdata = spi->dev.platform_data; jbt6k74_enter_state(jbt, jbt->normal_state); - if (jbt6k74_pdata->resuming) - (jbt6k74_pdata->resuming)(0); + if (pdata->resuming) + (pdata->resuming)(0); - dev_info(&spi->dev, "**** jbt6k74 resume end\n"); + dev_info(&spi->dev, "resumed\n"); return 0; } diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h index 27061909203..1ee06dfc883 100644 --- a/include/linux/mmc/sdio_ids.h +++ b/include/linux/mmc/sdio_ids.h @@ -27,6 +27,7 @@ #define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103 #define SDIO_DEVICE_ID_MARVELL_88W8688 0x9104 #define SDIO_VENDOR_ID_ATHEROS 0x0271 -#define SDIO_DEVICE_ID_ATHEROS_AR6000 0x0100 +#define SDIO_DEVICE_ID_ATHEROS_AR6001 0x0100 +#define SDIO_DEVICE_ID_ATHEROS_AR6002 0x0200 #endif diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c index d9fe7d1fffd..1358f6fe820 100644 --- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c @@ -104,7 +104,7 @@ static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream, /* set MCLK division for sample rate */ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, - S3C2410_IISMOD_32FS ); + S3C2410_IISMOD_32FS); if (ret < 0) return ret; @@ -116,7 +116,7 @@ static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream, /* set prescaler division for sample rate */ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, - S3C24XX_PRESCALE(4,4)); + S3C24XX_PRESCALE(4, 4)); if (ret < 0) return ret; @@ -210,7 +210,7 @@ static struct snd_soc_ops neo1973_gta02_voice_ops = { #define LM4853_AMP 1 #define LM4853_SPK 2 -static u8 lm4853_state=0; +static u8 lm4853_state; /* This has no effect, it exists only to maintain compatibility with * existing ALSA state files. @@ -220,11 +220,10 @@ static int lm4853_set_state(struct snd_kcontrol *kcontrol, { int val = ucontrol->value.integer.value[0]; - if(val) { + if (val) lm4853_state |= LM4853_AMP; - } else { + else lm4853_state &= ~LM4853_AMP; - } return 0; } @@ -242,12 +241,12 @@ static int lm4853_set_spk(struct snd_kcontrol *kcontrol, { int val = ucontrol->value.integer.value[0]; - if(val) { + if (val) { lm4853_state |= LM4853_SPK; - s3c2410_gpio_setpin(GTA02_GPIO_HP_IN,0); + s3c2410_gpio_setpin(GTA02_GPIO_HP_IN, 0); } else { lm4853_state &= ~LM4853_SPK; - s3c2410_gpio_setpin(GTA02_GPIO_HP_IN,1); + s3c2410_gpio_setpin(GTA02_GPIO_HP_IN, 1); } return 0; @@ -348,7 +347,8 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec) snd_soc_dapm_nc_pin(codec, "LINE2"); /* Add neo1973 gta02 specific widgets */ - snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, ARRAY_SIZE(wm8753_dapm_widgets)); + snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, + ARRAY_SIZE(wm8753_dapm_widgets)); /* add neo1973 gta02 specific controls */ for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_gta02_controls); i++) { @@ -378,8 +378,8 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec) /* * BT Codec DAI */ -static struct snd_soc_dai bt_dai = -{ .name = "Bluetooth", +static struct snd_soc_dai bt_dai = { + .name = "Bluetooth", .id = 0, .playback = { .channels_min = 1, @@ -423,8 +423,6 @@ static struct snd_soc_device neo1973_gta02_snd_devdata = { .codec_dev = &soc_codec_dev_wm8753, }; - - static struct platform_device *neo1973_gta02_snd_device; static int __init neo1973_gta02_init(void) @@ -433,7 +431,7 @@ static int __init neo1973_gta02_init(void) if (!machine_is_neo1973_gta02()) { printk(KERN_INFO - "Only GTA02 hardware supported by ASoc driver\n"); + "Only GTA02 is supported by this ASoC driver\n"); return -ENODEV; } @@ -468,18 +466,16 @@ static int __init neo1973_gta02_init(void) return ret; } +module_init(neo1973_gta02_init); static void __exit neo1973_gta02_exit(void) { snd_soc_unregister_dai(&bt_dai); platform_device_unregister(neo1973_gta02_snd_device); } - -module_init(neo1973_gta02_init); module_exit(neo1973_gta02_exit); /* Module information */ MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org"); MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 GTA02"); MODULE_LICENSE("GPL"); - |