diff options
-rw-r--r-- | arch/arm/configs/gta01_moredrivers_defconfig | 12 | ||||
-rw-r--r-- | arch/arm/configs/gta02_moredrivers_defconfig | 2 | ||||
-rw-r--r-- | arch/arm/configs/gta02_packaging_defconfig | 2 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/mach-gta01.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-s3c2442/mach-gta02.c | 12 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/include/plat/udc.h | 1 | ||||
-rw-r--r-- | drivers/mfd/glamo/Kconfig | 22 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-cmdq.c | 145 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-cmdq.h | 3 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-drm-drv.c | 4 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-drm-private.h | 5 | ||||
-rw-r--r-- | drivers/power/bq27000_battery.c | 12 | ||||
-rw-r--r-- | drivers/power/gta01_battery.c | 4 | ||||
-rw-r--r-- | drivers/power/pcf50633-charger.c | 3 | ||||
-rw-r--r-- | drivers/usb/gadget/s3c2410_udc.c | 28 | ||||
-rw-r--r-- | drivers/usb/gadget/u_ether.c | 8 |
16 files changed, 177 insertions, 87 deletions
diff --git a/arch/arm/configs/gta01_moredrivers_defconfig b/arch/arm/configs/gta01_moredrivers_defconfig index b60ebfba3b8..1f5883729dc 100644 --- a/arch/arm/configs/gta01_moredrivers_defconfig +++ b/arch/arm/configs/gta01_moredrivers_defconfig @@ -1610,7 +1610,7 @@ CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -CONFIG_RTC_DEBUG=y +# CONFIG_RTC_DEBUG is not set # # RTC interfaces @@ -1699,15 +1699,7 @@ CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE=y # CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT is not set CONFIG_ANDROID_TIMED_GPIO=y CONFIG_ANDROID_LOW_MEMORY_KILLER=y -CONFIG_ANDROID_HAS_WAKELOCK=y -CONFIG_ANDROID_HAS_EARLYSUSPEND=y -CONFIG_ANDROID_WAKELOCK=y -CONFIG_ANDROID_USER_WAKELOCK=y -CONFIG_ANDROID_EARLYSUSPEND=y -# CONFIG_NO_USER_SPACE_SCREEN_ACCESS_CONTROL is not set -CONFIG_ANDROID_CONSOLE_EARLYSUSPEND=y -# CONFIG_ANDROID_FB_EARLYSUSPEND is not set -CONFIG_ANDROID_POWER_ALARM=y +# CONFIG_ANDROID_WAKELOCK is not set CONFIG_ANDROID_PARANOID_NETWORK=y # diff --git a/arch/arm/configs/gta02_moredrivers_defconfig b/arch/arm/configs/gta02_moredrivers_defconfig index 1dbbbf63ce8..8d06cd6c70b 100644 --- a/arch/arm/configs/gta02_moredrivers_defconfig +++ b/arch/arm/configs/gta02_moredrivers_defconfig @@ -1694,7 +1694,7 @@ CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -CONFIG_RTC_DEBUG=y +# CONFIG_RTC_DEBUG is not set # # RTC interfaces diff --git a/arch/arm/configs/gta02_packaging_defconfig b/arch/arm/configs/gta02_packaging_defconfig index 237fd959510..dfdfb19a2f1 100644 --- a/arch/arm/configs/gta02_packaging_defconfig +++ b/arch/arm/configs/gta02_packaging_defconfig @@ -1697,7 +1697,7 @@ CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -CONFIG_RTC_DEBUG=y +# CONFIG_RTC_DEBUG is not set # # RTC interfaces diff --git a/arch/arm/mach-s3c2410/mach-gta01.c b/arch/arm/mach-s3c2410/mach-gta01.c index bddba990a74..1fe3eef2257 100644 --- a/arch/arm/mach-s3c2410/mach-gta01.c +++ b/arch/arm/mach-s3c2410/mach-gta01.c @@ -775,7 +775,6 @@ static struct spi_board_info gta01_spi_board_info[] = { /* controller_data */ /* irq */ .max_speed_hz = 10 * 1000 * 1000, - .bus_num = 1, /* chip_select */ }, }; diff --git a/arch/arm/mach-s3c2442/mach-gta02.c b/arch/arm/mach-s3c2442/mach-gta02.c index 072abd56759..e7a5f0a55a1 100644 --- a/arch/arm/mach-s3c2442/mach-gta02.c +++ b/arch/arm/mach-s3c2442/mach-gta02.c @@ -476,11 +476,22 @@ static void gta02_udc_vbus_draw(unsigned int ma) schedule_delayed_work(>a02_charger_work, GTA02_CHARGER_CONFIGURE_TIMEOUT); } + +static int gta02_udc_vbus_status(void) +{ + struct pcf50633 *pcf = gta02_pcf; + + if (!gta02_pcf) + return -ENODEV; + + return !!(pcf50633_mbc_get_status(pcf) & PCF50633_MBC_USB_ONLINE); +} #else /* !CONFIG_CHARGER_PCF50633 */ #define gta02_get_charger_online_status NULL #define gta02_get_charger_active_status NULL #define gta02_pmu_event_callback NULL #define gta02_udc_vbus_draw NULL +#define gta02_udc_vbus_status NULL #endif static struct platform_device gta01_pm_gps_dev = { @@ -954,6 +965,7 @@ static void gta02_udc_command(enum s3c2410_udc_cmd_e cmd) static struct s3c2410_udc_mach_info gta02_udc_cfg = { .vbus_draw = gta02_udc_vbus_draw, .udc_command = gta02_udc_command, + .get_vbus_status= gta02_udc_vbus_status, }; diff --git a/arch/arm/plat-s3c24xx/include/plat/udc.h b/arch/arm/plat-s3c24xx/include/plat/udc.h index 546bb4008f4..763aeba628e 100644 --- a/arch/arm/plat-s3c24xx/include/plat/udc.h +++ b/arch/arm/plat-s3c24xx/include/plat/udc.h @@ -27,6 +27,7 @@ enum s3c2410_udc_cmd_e { struct s3c2410_udc_mach_info { void (*udc_command)(enum s3c2410_udc_cmd_e); void (*vbus_draw)(unsigned int ma); + int (*get_vbus_status)(void); unsigned int vbus_pin; unsigned char vbus_pin_inverted; }; diff --git a/drivers/mfd/glamo/Kconfig b/drivers/mfd/glamo/Kconfig index 3b942ab0a6d..7db45288c38 100644 --- a/drivers/mfd/glamo/Kconfig +++ b/drivers/mfd/glamo/Kconfig @@ -35,18 +35,20 @@ config MFD_GLAMO_FB_XGLAMO_WORKAROUND If unsure, say N. config MFD_GLAMO_SPI_GPIO - tristate "Glamo GPIO SPI bitbang support" - depends on MFD_GLAMO - help - Enable a bitbanging SPI adapter driver for the Smedia Glamo. + tristate "Glamo GPIO SPI bitbang support" + depends on MFD_GLAMO + select SPI_BITBANG + + help + Enable a bitbanging SPI adapter driver for the Smedia Glamo. config MFD_GLAMO_SPI_FB - tristate "Glamo LCM control channel SPI support" - depends on MFD_GLAMO_FB - help - Enable a bitbanging SPI adapter driver for the Smedia Glamo LCM - control channel. This SPI interface is frequently used to - interconnect the LCM control interface. + tristate "Glamo LCM control channel SPI support" + depends on MFD_GLAMO_FB + help + Enable a bitbanging SPI adapter driver for the Smedia Glamo LCM + control channel. This SPI interface is frequently used to + interconnect the LCM control interface. config MFD_GLAMO_MCI tristate "Glamo S3C SD/MMC Card Interface support" diff --git a/drivers/mfd/glamo/glamo-cmdq.c b/drivers/mfd/glamo/glamo-cmdq.c index bdae9859854..f2a124a6e18 100644 --- a/drivers/mfd/glamo/glamo-cmdq.c +++ b/drivers/mfd/glamo/glamo-cmdq.c @@ -2,6 +2,7 @@ * SMedia Glamo 336x/337x command queue handling * * Copyright (C) 2008-2009 Thomas White <taw@bitwiz.org.uk> + * Copyright (C) 2009 Andreas Pokorny <andreas.pokorny@gmail.com> * Based on xf86-video-glamo (see below for details) * * All rights reserved. @@ -49,7 +50,6 @@ * OF THIS SOFTWARE. */ - #include <drm/drmP.h> #include <drm/glamo_drm.h> @@ -58,18 +58,40 @@ #include "glamo-regs.h" -static void reg_write(struct glamodrm_handle *gdrm, +static inline void reg_write(struct glamodrm_handle *gdrm, u_int16_t reg, u_int16_t val) { iowrite16(val, gdrm->reg_base + reg); } -static u16 reg_read(struct glamodrm_handle *gdrm, u_int16_t reg) +static inline u16 reg_read(struct glamodrm_handle *gdrm, u_int16_t reg) { return ioread16(gdrm->reg_base + reg); } +static u32 glamo_get_read(struct glamodrm_handle *gdrm) +{ + /* we could turn off clock here */ + u32 ring_read = reg_read(gdrm, GLAMO_REG_CMDQ_READ_ADDRL); + ring_read |= ((reg_read(gdrm, GLAMO_REG_CMDQ_READ_ADDRH) + & 0x7) << 16); + + return ring_read; +} + +static u32 glamo_get_write(struct glamodrm_handle *gdrm) +{ + u32 ring_write = reg_read(gdrm, GLAMO_REG_CMDQ_WRITE_ADDRL); + ring_write |= ((reg_read(gdrm, GLAMO_REG_CMDQ_WRITE_ADDRH) + & 0x7) << 16); + + return ring_write; +} + +#if 0 + +/* hopefully we will never need that again */ static void glamo_cmdq_wait(struct glamodrm_handle *gdrm, enum glamo_engine engine) @@ -118,6 +140,7 @@ glamo_cmdq_wait(struct glamodrm_handle *gdrm, enum glamo_engine engine) ring_read); } } +#endif /* Add commands to the ring buffer */ @@ -127,8 +150,11 @@ static int glamo_add_to_ring(struct glamodrm_handle *gdrm, u16 *addr, size_t ring_write, ring_read; size_t new_ring_write; - ring_write = reg_read(gdrm, GLAMO_REG_CMDQ_WRITE_ADDRL); - ring_write |= (reg_read(gdrm, GLAMO_REG_CMDQ_WRITE_ADDRH) << 16); + printk( KERN_INFO "[glamo-drm] glamo add to ring %d bytes, ring_read: %d\n", count, glamo_get_read(gdrm)); + + up(&gdrm->add_to_ring); + + ring_write = glamo_get_write(gdrm); /* Calculate where we'll end up */ new_ring_write = (ring_write + count) % GLAMO_CMDQ_SIZE; @@ -138,37 +164,28 @@ static int glamo_add_to_ring(struct glamodrm_handle *gdrm, u16 *addr, /* Loop while the read pointer is between the old and new * positions */ do { - ring_read = reg_read(gdrm, GLAMO_REG_CMDQ_READ_ADDRL); - ring_read |= ((reg_read(gdrm, GLAMO_REG_CMDQ_READ_ADDRH) - & 0x7) << 16); + ring_read = glamo_get_read(gdrm); } while (ring_read > ring_write && ring_read < new_ring_write); - } else { + } else { /* Same, but kind of inside-out */ do { - ring_read = reg_read(gdrm, GLAMO_REG_CMDQ_READ_ADDRL); - ring_read |= ((reg_read(gdrm, GLAMO_REG_CMDQ_READ_ADDRH) - & 0x7) << 16); + ring_read = glamo_get_read(gdrm); } while (ring_read > ring_write || ring_read < new_ring_write); } /* Are we about to wrap around? */ if (ring_write >= new_ring_write) { - size_t rest_size; - int i; + u32 rest_size; printk(KERN_INFO "[glamo-drm] CmdQ wrap-around...\n"); /* Wrap around */ rest_size = GLAMO_CMDQ_SIZE - ring_write; /* Space left */ /* Write from current position to end */ - for ( i=0; i<rest_size; i++ ) { - iowrite16(*(addr+i), gdrm->cmdq_base+ring_write+(i*2)); - } + memcpy_toio(gdrm->cmdq_base+ring_write, addr, rest_size); /* Write from start */ - for ( i=0; i<(count-rest_size); i++ ) { - iowrite16(*(addr+rest_size+i), gdrm->cmdq_base+(i*2)); - } + memcpy_toio(gdrm->cmdq_base, addr+(rest_size>>1), count - rest_size); /* ring_write being 0 will result in a deadlock because the * cmdq read will never stop. To avoid such an behaviour insert @@ -181,7 +198,7 @@ static int glamo_add_to_ring(struct glamodrm_handle *gdrm, u16 *addr, /* Suppose we just filled the WHOLE ring buffer, and so the * write position ends up in the same place as it started. - * No change in pointer means no activity from the command + * No change in poginter means no activity from the command * queue engine. So, insert a no-op */ if (ring_write == new_ring_write) { iowrite16(0x0000, gdrm->cmdq_base + new_ring_write); @@ -191,32 +208,26 @@ static int glamo_add_to_ring(struct glamodrm_handle *gdrm, u16 *addr, } else { - int i; - /* The easy case */ - for ( i=0; i<count/2; i++ ) { /* Number of words */ - iowrite16(*(addr+i), gdrm->cmdq_base+ring_write+(i*2)); - } + memcpy_toio(gdrm->cmdq_base+ring_write, addr,count); } - /* Before changing write position, read has to stop - * (Brought across from xf86-video-glamo) - * TAW: Really? Is pausing the clock not enough? */ - glamo_cmdq_wait(gdrm, GLAMO_ENGINE_CMDQ); - /* Note that CLOCK_2D_EN_M6CLK has nothing to do with the 2D engine */ - glamo_engine_clkreg_set(gdrm->glamo_core, GLAMO_ENGINE_2D, - GLAMO_CLOCK_2D_EN_M6CLK, 0x0000); reg_write(gdrm, GLAMO_REG_CMDQ_WRITE_ADDRH, - (new_ring_write >> 16) & 0x7f); + (new_ring_write >> 16) & 0x7f); reg_write(gdrm, GLAMO_REG_CMDQ_WRITE_ADDRL, - new_ring_write & 0xffff); - glamo_engine_clkreg_set(gdrm->glamo_core, GLAMO_ENGINE_2D, - GLAMO_CLOCK_2D_EN_M6CLK, 0xffff); + new_ring_write & 0xffff); + + down(&gdrm->add_to_ring); + + printk( KERN_INFO "[glamo-drm] IOCTL2 CMDQ at: %d-%d, CMDQ CTRL: %d, CMDQ STATUS: %d\n", + glamo_get_read(gdrm), glamo_get_write(gdrm), + reg_read(gdrm, GLAMO_REG_CMDQ_CONTROL), + reg_read(gdrm, GLAMO_REG_CMDQ_STATUS) ); + return 0; } - /* Return true for a legal sequence of commands, otherwise false */ static int glamo_sanitize_buffer(u16 *cmds, unsigned int count) { @@ -231,16 +242,16 @@ static int glamo_do_relocation(struct glamodrm_handle *gdrm, struct drm_device *dev, struct drm_file *file_priv) { - uint32_t *handles; + u32 *handles; int *offsets; int nobjs = cbuf->nobjs; int i; if ( nobjs > 32 ) return -EINVAL; /* Get real... */ - handles = drm_alloc(nobjs*sizeof(uint32_t), DRM_MEM_DRIVER); + handles = drm_alloc(nobjs*sizeof(u32), DRM_MEM_DRIVER); if ( handles == NULL ) return -1; - if ( copy_from_user(handles, cbuf->objs, nobjs*sizeof(uint32_t)) ) + if ( copy_from_user(handles, cbuf->objs, nobjs*sizeof(u32)) ) return -1; offsets = drm_alloc(nobjs*sizeof(int), DRM_MEM_DRIVER); @@ -250,7 +261,7 @@ static int glamo_do_relocation(struct glamodrm_handle *gdrm, for ( i=0; i<nobjs; i++ ) { - uint32_t handle = handles[i]; + u32 handle = handles[i]; int offset = offsets[i]; struct drm_gem_object *obj; struct drm_glamo_gem_object *gobj; @@ -310,6 +321,7 @@ fail: int glamo_ioctl_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv) { + int ret = 0; struct glamodrm_handle *gdrm; unsigned int count; drm_glamo_cmd_buffer_t *cbuf = data; @@ -317,33 +329,48 @@ int glamo_ioctl_cmdbuf(struct drm_device *dev, void *data, gdrm = dev->dev_private; + printk( KERN_INFO "[glamo-drm] IOCTL CMDQ at: %d-%d, CMDQ CTRL: %d, CMDQ STATUS: %d\n", + glamo_get_read(gdrm), glamo_get_write(gdrm), + reg_read(gdrm, GLAMO_REG_CMDQ_CONTROL), + reg_read(gdrm, GLAMO_REG_CMDQ_STATUS) ); + + count = cbuf->bufsz; if ( count > PAGE_SIZE ) return -EINVAL; cmds = drm_alloc(count, DRM_MEM_DRIVER); if ( cmds == NULL ) return -ENOMEM; - if ( copy_from_user(cmds, cbuf->buf, count) ) return -EINVAL; + if ( copy_from_user(cmds, cbuf->buf, count) ) { + printk( KERN_WARNING "[glamo-drm] copy from user failed\n"); + ret = -EINVAL; + goto cleanup; + } /* Check the buffer isn't going to tell Glamo to enact naughtiness */ - if ( !glamo_sanitize_buffer(cmds, count) ) return -EINVAL; + if ( !glamo_sanitize_buffer(cmds, count) ) { + printk( KERN_WARNING "[glamo-drm] sanitize buffer failed\n"); + ret = -EINVAL; + goto cleanup; + } /* Perform relocation, if necessary */ if ( cbuf->nobjs ) { if ( glamo_do_relocation(gdrm, cbuf, cmds, dev, file_priv) ) - return -EINVAL; /* Relocation failed */ + { + printk( KERN_WARNING "[glamo-drm] Relocation failed\n"); + ret = -EINVAL; + goto cleanup; + } } glamo_add_to_ring(gdrm, cmds, count); - /* Having the CPU wait for the CPU is, to put it mildly, - * less than optimal. - * TODO: Avoid doing this, by some suitable means */ - glamo_cmdq_wait(gdrm, GLAMO_ENGINE_ALL); +cleanup: drm_free(cmds, 1, DRM_MEM_DRIVER); - return 0; + return ret; } @@ -351,6 +378,8 @@ int glamo_cmdq_init(struct glamodrm_handle *gdrm) { unsigned int i; + init_MUTEX(&gdrm->add_to_ring); + /* Enable 2D and 3D */ glamo_engine_enable(gdrm->glamo_core, GLAMO_ENGINE_2D); glamo_engine_reset(gdrm->glamo_core, GLAMO_ENGINE_2D); @@ -373,16 +402,22 @@ int glamo_cmdq_init(struct glamodrm_handle *gdrm) reg_write(gdrm, GLAMO_REG_CMDQ_LEN, (GLAMO_CMDQ_SIZE >> 10)-1); reg_write(gdrm, GLAMO_REG_CMDQ_WRITE_ADDRH, 0); reg_write(gdrm, GLAMO_REG_CMDQ_WRITE_ADDRL, 0); - reg_write(gdrm, GLAMO_REG_CMDQ_READ_ADDRH, 0); - reg_write(gdrm, GLAMO_REG_CMDQ_READ_ADDRL, 0); reg_write(gdrm, GLAMO_REG_CMDQ_CONTROL, 1 << 12 | /* Turbo flip (?) */ - 5 << 8 | /* No interrupt */ + 5 << 8 | /* no interrupt */ 8 << 4); /* HQ threshold */ - /* Wait for things to settle down */ - glamo_cmdq_wait(gdrm, GLAMO_ENGINE_ALL); + printk( KERN_INFO "[glamo-drm] INIT CMDQ at: %d-%d, CMDQ CTRL: %d, CMDQ STATUS: %d\n", + glamo_get_read(gdrm), glamo_get_write(gdrm), + reg_read(gdrm, GLAMO_REG_CMDQ_CONTROL), + reg_read(gdrm, GLAMO_REG_CMDQ_STATUS) ); + + return 0; +} + +int glamo_cmdq_shutdown(struct glamodrm_handle *gdrm) +{ return 0; } diff --git a/drivers/mfd/glamo/glamo-cmdq.h b/drivers/mfd/glamo/glamo-cmdq.h index 4bc6b717115..35c8bea1dcb 100644 --- a/drivers/mfd/glamo/glamo-cmdq.h +++ b/drivers/mfd/glamo/glamo-cmdq.h @@ -1,6 +1,7 @@ /* Smedia Glamo 336x/337x command queue handling * * Copyright (c) 2008-2009 Thomas White <taw@bitwiz.org.uk> + * Copyright (c) 2009 Andreas Pokorny <andreas.pokorny@gmail.com> * Based on xf86-video-glamo * Copyright 2007 OpenMoko, Inc. * Copyright © 2009 Lars-Peter Clausen <lars@metafoo.de> @@ -34,8 +35,8 @@ extern int glamo_ioctl_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int glamo_cmdq_init(struct glamodrm_handle *gdrm); +extern int glamo_cmdq_shutdown(struct glamodrm_handle *gdrm); extern void glamo_cmdq_suspend(struct glamodrm_handle *gdrm); extern void glamo_cmdq_resume(struct glamodrm_handle *gdrm); - #endif /* __GLAMO_CMDQ_H */ diff --git a/drivers/mfd/glamo/glamo-drm-drv.c b/drivers/mfd/glamo/glamo-drm-drv.c index d71da8850ac..9725968a196 100644 --- a/drivers/mfd/glamo/glamo-drm-drv.c +++ b/drivers/mfd/glamo/glamo-drm-drv.c @@ -2,6 +2,7 @@ * * Copyright (C) 2009 Openmoko, Inc. Jorge Luis Zapata <turran@openmoko.com> * Copyright (C) 2008-2009 Thomas White <taw@bitwiz.org.uk> + * Copyright (C) 2009 Andreas Pokorny <andreas.pokorny@gmail.com> * * All rights reserved. * @@ -331,6 +332,9 @@ static int glamodrm_remove(struct platform_device *pdev) { struct glamodrm_handle *gdrm = platform_get_drvdata(pdev); + glamo_buffer_final(gdrm); + glamo_cmdq_shutdown(gdrm); + drm_exit(&glamodrm_drm_driver); platform_set_drvdata(pdev, NULL); diff --git a/drivers/mfd/glamo/glamo-drm-private.h b/drivers/mfd/glamo/glamo-drm-private.h index 59030cb2313..3f01f1fd6a1 100644 --- a/drivers/mfd/glamo/glamo-drm-private.h +++ b/drivers/mfd/glamo/glamo-drm-private.h @@ -1,6 +1,7 @@ /* Smedia Glamo 336x/337x DRM private bits * * Copyright (C) 2008-2009 Thomas White <taw@bitwiz.org.uk> + * Copyright (C) 2009 Andreas Pokorny <andreas.pokorny@gmail.com> * Based on xf86-video-glamo * Copyright 2007 OpenMoko, Inc. * Copyright © 2009 Lars-Peter Clausen <lars@metafoo.de> @@ -29,6 +30,7 @@ #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/semaphore.h> #include "glamo-core.h" @@ -70,6 +72,9 @@ struct glamodrm_handle { /* Memory management */ struct drm_mm *mmgr; + /* semaphore against concurrent ioctl */ + struct semaphore add_to_ring; + /* Saved state */ u_int16_t saved_clock; u_int16_t saved_width; diff --git a/drivers/power/bq27000_battery.c b/drivers/power/bq27000_battery.c index 9f0f1a96720..593cbe6f752 100644 --- a/drivers/power/bq27000_battery.c +++ b/drivers/power/bq27000_battery.c @@ -115,6 +115,7 @@ struct bq27000_bat_regs { int ai; int flags; int lmd; + int nac; int rsoc; int temp; int tte; @@ -170,9 +171,11 @@ static int hdq_read16(struct bq27000_device_info *di, int address) static void bq27000_battery_external_power_changed(struct power_supply *psy) { - struct bq27000_device_info *di = container_of(psy, struct bq27000_device_info, bat); + struct bq27000_device_info *di = + container_of(psy, struct bq27000_device_info, bat); dev_dbg(di->dev, "%s\n", __FUNCTION__); + cancel_delayed_work(&di->work); schedule_delayed_work(&di->work, 0); } @@ -269,6 +272,11 @@ use_bat: return di->regs.lmd; val->intval = (di->regs.lmd * 3570) / di->pdata->rsense_mohms; break; + case POWER_SUPPLY_PROP_CHARGE_NOW: + if (di->regs.nac < 0) + return di->regs.nac; + val->intval = (di->regs.nac * 3570) / di->pdata->rsense_mohms; + break; case POWER_SUPPLY_PROP_TEMP: if (di->regs.temp < 0) return di->regs.temp; @@ -321,6 +329,7 @@ static void bq27000_battery_work(struct work_struct *work) regs.ai = hdq_read16(di, BQ27000_AI_L); regs.flags = (di->pdata->hdq_read)(BQ27000_FLAGS); regs.lmd = hdq_read16(di, BQ27000_LMD_L); + regs.nac = hdq_read16(di, BQ27000_NAC_L); regs.rsoc = (di->pdata->hdq_read)(BQ27000_RSOC); regs.temp = hdq_read16(di, BQ27000_TEMP_L); regs.tte = hdq_read16(di, BQ27000_TTE_L); @@ -343,6 +352,7 @@ static enum power_supply_property bq27000_battery_props[] = { POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CHARGE_FULL, + POWER_SUPPLY_PROP_CHARGE_NOW, POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_TECHNOLOGY, POWER_SUPPLY_PROP_PRESENT, diff --git a/drivers/power/gta01_battery.c b/drivers/power/gta01_battery.c index 909f7fe16d9..81a0fe7387e 100644 --- a/drivers/power/gta01_battery.c +++ b/drivers/power/gta01_battery.c @@ -19,6 +19,7 @@ struct gta01_battery { }; static enum power_supply_property gta01_bat_props[] = { + POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_NOW, @@ -43,6 +44,9 @@ static int gta01_bat_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_CURRENT_NOW: val->intval = bat->pdata->get_current(); break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = 1; /* You must never run GTA01 without battery. */ + break; default: return -EINVAL; } diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c index 8772604ae1a..1bdb9906201 100644 --- a/drivers/power/pcf50633-charger.c +++ b/drivers/power/pcf50633-charger.c @@ -114,6 +114,9 @@ int pcf50633_mbc_get_status(struct pcf50633 *pcf) struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev); int status = 0; + if (!mbc) + return 0; + if (mbc->usb_online) status |= PCF50633_MBC_USB_ONLINE; if (mbc->usb_active) diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 1a185c1194e..c8dca979b04 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -74,6 +74,7 @@ static void __iomem *base_addr; static u64 rsrc_start; static u64 rsrc_len; static struct dentry *s3c2410_udc_debugfs_root; +static struct timer_list vbus_poll_timer; static inline u32 udc_read(u32 reg) { @@ -1526,6 +1527,20 @@ static irqreturn_t s3c2410_udc_vbus_irq(int irq, void *_dev) return IRQ_HANDLED; } +static void s3c2410_udc_vbus_poll(unsigned long _data) +{ + struct s3c2410_udc *data = (struct s3c2410_udc *)_data; + int v; + + dprintk(DEBUG_NORMAL, "%s()\n", __func__); + if (udc_info && udc_info->get_vbus_status) { + v = udc_info->get_vbus_status(); + if ((v > -1) && (v != data->vbus)) + s3c2410_udc_vbus_session(&data->gadget, v); + mod_timer(&vbus_poll_timer, jiffies + msecs_to_jiffies(900)); + } +} + static int s3c2410_vbus_draw(struct usb_gadget *_gadget, unsigned ma) { dprintk(DEBUG_NORMAL, "%s()\n", __func__); @@ -1683,6 +1698,11 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) goto register_error; } + if (udc_info && udc_info->get_vbus_status && !udc_info->vbus_pin) { + mod_timer(&vbus_poll_timer, jiffies + msecs_to_jiffies(50)); + return 0; /* just return, vbus change will enable udc */ + } + /* Enable udc */ s3c2410_udc_enable(udc); @@ -1713,6 +1733,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) if (driver->disconnect) driver->disconnect(&udc->gadget); + driver->unbind(&udc->gadget); device_del(&udc->gadget.dev); udc->driver = NULL; @@ -1899,6 +1920,11 @@ static int s3c2410_udc_probe(struct platform_device *pdev) } dev_dbg(dev, "got irq %i\n", irq); + } else if (udc_info && udc_info->get_vbus_status) { + udc->vbus = 0; + init_timer(&vbus_poll_timer); + vbus_poll_timer.function = s3c2410_udc_vbus_poll; + vbus_poll_timer.data = (unsigned long) udc; } else { udc->vbus = 1; } @@ -1947,6 +1973,8 @@ static int s3c2410_udc_remove(struct platform_device *pdev) if (udc_info && udc_info->vbus_pin > 0) { irq = gpio_to_irq(udc_info->vbus_pin); free_irq(irq, udc); + } else if (udc_info && udc_info->get_vbus_status) { + del_timer_sync(&vbus_poll_timer); } free_irq(IRQ_USBD, udc); diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 96d65ca06ec..4007770f7ed 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -175,12 +175,6 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p) strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info); } -static u32 eth_get_link(struct net_device *net) -{ - struct eth_dev *dev = netdev_priv(net); - return dev->gadget->speed != USB_SPEED_UNKNOWN; -} - /* REVISIT can also support: * - WOL (by tracking suspends and issuing remote wakeup) * - msglevel (implies updated messaging) @@ -189,7 +183,7 @@ static u32 eth_get_link(struct net_device *net) static struct ethtool_ops ops = { .get_drvinfo = eth_get_drvinfo, - .get_link = eth_get_link + .get_link = ethtool_op_get_link, }; static void defer_kevent(struct eth_dev *dev, int flag) |