From 4a102b4d144f0422eb8b0a59c7cb194bf12163a9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 23 Jan 2014 15:53:45 -0800 Subject: drivers/mailbox/omap: make mbox->irq signed for error handling There is a bug in omap2_mbox_probe() where we try do: mbox->irq = platform_get_irq(pdev, info->irq_id); if (mbox->irq < 0) { The problem is that mbox->irq is unsigned so the error handling doesn't work. I've changed it to a signed integer. Signed-off-by: Dan Carpenter Cc: Suman Anna Cc: Greg Kroah-Hartman Cc: Omar Ramirez Luna Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mailbox/omap-mbox.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mailbox/omap-mbox.h b/drivers/mailbox/omap-mbox.h index 6cd38fc68599..86d7518cd13b 100644 --- a/drivers/mailbox/omap-mbox.h +++ b/drivers/mailbox/omap-mbox.h @@ -52,7 +52,7 @@ struct omap_mbox_queue { struct omap_mbox { const char *name; - unsigned int irq; + int irq; struct omap_mbox_queue *txq, *rxq; struct omap_mbox_ops *ops; struct device *dev; -- cgit v1.2.3 From a3b25d9b774fbda2e6add28cf792941fd98fa999 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Thu, 23 Jan 2014 15:53:46 -0800 Subject: drivers/block/Kconfig: update RAM block device module name RAM block device support module name changed to brd.ko some years ago with an "rd" alias to match previous module implementation. This patch updates its Kconfig definition. Signed-off-by: Fabian Frederick Acked-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 86b9f37d102e..9ffa90c6201c 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -368,7 +368,8 @@ config BLK_DEV_RAM For details, read . To compile this driver as a module, choose M here: the - module will be called rd. + module will be called brd. An alias "rd" has been defined + for historical reasons. Most normal users won't need the RAM disk functionality, and can thus say N here. -- cgit v1.2.3 From e13e64ece037104f5b04d0e98929ad2149c5bb09 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 23 Jan 2014 15:54:03 -0800 Subject: drivers/gpu/drm/gma500/backlight.c: fix a defined-but-not-used warning for do_gma_backlight_set() Fix the following warning: drivers/gpu/drm/gma500/backlight.c:29:13: warning: 'do_gma_backlight_set' defined but not used [-Wunused-function] by moving the entire function inside the conditional section currently inside of it. All the places that call it are so conditionalised. Signed-off-by: David Howells Cc: Alan Cox Cc: Greg Kroah-Hartman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpu/drm/gma500/backlight.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/gma500/backlight.c b/drivers/gpu/drm/gma500/backlight.c index 143eba3309c5..ea7dfc59d796 100644 --- a/drivers/gpu/drm/gma500/backlight.c +++ b/drivers/gpu/drm/gma500/backlight.c @@ -26,13 +26,13 @@ #include "intel_bios.h" #include "power.h" +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE static void do_gma_backlight_set(struct drm_device *dev) { -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE struct drm_psb_private *dev_priv = dev->dev_private; backlight_update_status(dev_priv->backlight_device); -#endif } +#endif void gma_backlight_enable(struct drm_device *dev) { -- cgit v1.2.3 From f30c0c32b69b6467fa23e2798432262428587471 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 23 Jan 2014 15:54:04 -0800 Subject: drivers/mfd/max8998.c: fix pointer-integer size mismatch warning in max8998_i2c_get_driver_data() Fix up the following pointer-integer size mismatch warning in max8998_i2c_get_driver_data(): drivers/mfd/max8998.c: In function 'max8998_i2c_get_driver_data': drivers/mfd/max8998.c:178:10: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] return (int)match->data; ^ Signed-off-by: David Howells Cc: Tomasz Figa Cc: Mark Brown Cc: Samuel Ortiz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mfd/max8998.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index f47eaa70eae0..612ca404e150 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c @@ -175,7 +175,7 @@ static inline int max8998_i2c_get_driver_data(struct i2c_client *i2c, if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) { const struct of_device_id *match; match = of_match_node(max8998_dt_match, i2c->dev.of_node); - return (int)match->data; + return (int)(long)match->data; } return (int)id->driver_data; -- cgit v1.2.3 From c6d5f989e14f36d5ff71a9b79a6d3c3bf06c185f Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 23 Jan 2014 15:54:05 -0800 Subject: drivers/mfd/tps65217.c: fix pointer-integer size mismatch warning in tps65217_probe() Fix up the following pointer-integer size mismatch warning in tps65217_probe(): drivers/mfd/tps65217.c: In function 'tps65217_probe': drivers/mfd/tps65217.c:173:13: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] chip_id = (unsigned int)match->data; ^ Signed-off-by: David Howells Cc: AnilKumar Ch Cc: Samuel Ortiz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mfd/tps65217.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c index 6939ae56c2e1..966cf65c5c36 100644 --- a/drivers/mfd/tps65217.c +++ b/drivers/mfd/tps65217.c @@ -170,7 +170,7 @@ static int tps65217_probe(struct i2c_client *client, "Failed to find matching dt id\n"); return -EINVAL; } - chip_id = (unsigned int)match->data; + chip_id = (unsigned int)(unsigned long)match->data; status_off = of_property_read_bool(client->dev.of_node, "ti,pmic-shutdown-controller"); } -- cgit v1.2.3 From a79530e4d8c8ef2bece88f8dab680e541162f010 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 23 Jan 2014 15:54:06 -0800 Subject: drivers/video/aty/aty128fb.c: fix a warning pertaining to the aty128fb backlight variable Fix the following warning in the aty128fb driver: drivers/video/aty/aty128fb.c:363:12: warning: 'backlight' defined but not used [-Wunused-variable] static int backlight = 0; ^ as the variable's value is only read if CONFIG_FB_ATY128_BACKLIGHT=y. The variable is also set if MODULE is unset[*]. [*] I wonder if the conditional wrapper around aty128fb_setup() should be using CONFIG_MODULE rather than MODULE. Signed-off-by: David Howells Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/aty/aty128fb.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index 12ca031877d4..52108be69e77 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c @@ -357,11 +357,13 @@ static int default_lcd_on = 1; static bool mtrr = true; #endif +#ifdef CONFIG_FB_ATY128_BACKLIGHT #ifdef CONFIG_PMAC_BACKLIGHT static int backlight = 1; #else static int backlight = 0; #endif +#endif /* PLL constants */ struct aty128_constants { @@ -1671,7 +1673,9 @@ static int aty128fb_setup(char *options) default_crt_on = simple_strtoul(this_opt+4, NULL, 0); continue; } else if (!strncmp(this_opt, "backlight:", 10)) { +#ifdef CONFIG_FB_ATY128_BACKLIGHT backlight = simple_strtoul(this_opt+10, NULL, 0); +#endif continue; } #ifdef CONFIG_MTRR -- cgit v1.2.3 From 59d42cd43c7335a3a8081fd6ee54ea41b0c239be Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 23 Jan 2014 15:54:07 -0800 Subject: drivers/vlynq/vlynq.c: fix another resource size off by 1 error We fixed the call to request_mem_region() in commit 3354f73b24c6 ("drivers/vlynq/vlynq.c: fix resource size off by 1 error"). But we need to fix the call the release_mem_region() as well. Signed-off-by: Dan Carpenter Cc: Florian Fainelli Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/vlynq/vlynq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/vlynq/vlynq.c b/drivers/vlynq/vlynq.c index 7b07135ab26e..c0227f9418eb 100644 --- a/drivers/vlynq/vlynq.c +++ b/drivers/vlynq/vlynq.c @@ -762,7 +762,8 @@ static int vlynq_remove(struct platform_device *pdev) device_unregister(&dev->dev); iounmap(dev->local); - release_mem_region(dev->regs_start, dev->regs_end - dev->regs_start); + release_mem_region(dev->regs_start, + dev->regs_end - dev->regs_start + 1); kfree(dev); -- cgit v1.2.3 From 0ec585d320acb3e9c33b2b2ba9cefb4a62483d42 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Jan 2014 15:54:24 -0800 Subject: backlight: jornada720: use devm_backlight_device_register() Use devm_backlight_device_register() to make cleanup paths simpler, and remove unnecessary remove(). Signed-off-by: Jingoo Han Cc: Tomi Valkeinen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/jornada720_bl.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c index 3ccb89340f22..6ce96b4a8796 100644 --- a/drivers/video/backlight/jornada720_bl.c +++ b/drivers/video/backlight/jornada720_bl.c @@ -115,9 +115,10 @@ static int jornada_bl_probe(struct platform_device *pdev) memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; props.max_brightness = BL_MAX_BRIGHT; - bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, - &jornada_bl_ops, &props); + bd = devm_backlight_device_register(&pdev->dev, S1D_DEVICENAME, + &pdev->dev, NULL, &jornada_bl_ops, + &props); if (IS_ERR(bd)) { ret = PTR_ERR(bd); dev_err(&pdev->dev, "failed to register device, err=%x\n", ret); @@ -139,18 +140,8 @@ static int jornada_bl_probe(struct platform_device *pdev) return 0; } -static int jornada_bl_remove(struct platform_device *pdev) -{ - struct backlight_device *bd = platform_get_drvdata(pdev); - - backlight_device_unregister(bd); - - return 0; -} - static struct platform_driver jornada_bl_driver = { .probe = jornada_bl_probe, - .remove = jornada_bl_remove, .driver = { .name = "jornada_bl", }, -- cgit v1.2.3 From 0561c1794a0df435631474a99c24220b9fc1bbfe Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Jan 2014 15:54:25 -0800 Subject: backlight: hp680_bl: use devm_backlight_device_register() Use devm_backlight_device_register() to make cleanup paths simpler. Signed-off-by: Jingoo Han Cc: Tomi Valkeinen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/hp680_bl.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index 00076ecfe9b8..8ea42b8d9bc8 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c @@ -110,8 +110,8 @@ static int hp680bl_probe(struct platform_device *pdev) memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; props.max_brightness = HP680_MAX_INTENSITY; - bd = backlight_device_register("hp680-bl", &pdev->dev, NULL, - &hp680bl_ops, &props); + bd = devm_backlight_device_register(&pdev->dev, "hp680-bl", &pdev->dev, + NULL, &hp680bl_ops, &props); if (IS_ERR(bd)) return PTR_ERR(bd); @@ -131,8 +131,6 @@ static int hp680bl_remove(struct platform_device *pdev) bd->props.power = 0; hp680bl_send_intensity(bd); - backlight_device_unregister(bd); - return 0; } -- cgit v1.2.3 From c76d1022b4ce399cfad835cc505b4f1d914f53cb Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Jan 2014 15:54:26 -0800 Subject: backlight: omap1: use devm_backlight_device_register() Use devm_backlight_device_register() to make cleanup paths simpler, and remove unnecessary remove(). Signed-off-by: Jingoo Han Cc: Tomi Valkeinen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/omap1_bl.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c index ac11a4650c19..a0dcd88ac74f 100644 --- a/drivers/video/backlight/omap1_bl.c +++ b/drivers/video/backlight/omap1_bl.c @@ -146,8 +146,8 @@ static int omapbl_probe(struct platform_device *pdev) memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; props.max_brightness = OMAPBL_MAX_INTENSITY; - dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops, - &props); + dev = devm_backlight_device_register(&pdev->dev, "omap-bl", &pdev->dev, + bl, &omapbl_ops, &props); if (IS_ERR(dev)) return PTR_ERR(dev); @@ -170,20 +170,10 @@ static int omapbl_probe(struct platform_device *pdev) return 0; } -static int omapbl_remove(struct platform_device *pdev) -{ - struct backlight_device *dev = platform_get_drvdata(pdev); - - backlight_device_unregister(dev); - - return 0; -} - static SIMPLE_DEV_PM_OPS(omapbl_pm_ops, omapbl_suspend, omapbl_resume); static struct platform_driver omapbl_driver = { .probe = omapbl_probe, - .remove = omapbl_remove, .driver = { .name = "omap-bl", .pm = &omapbl_pm_ops, -- cgit v1.2.3 From 443956fdd501bdfa8471191ef23d1432ea5fa928 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Jan 2014 15:54:27 -0800 Subject: backlight: ot200_bl: use devm_backlight_device_register() Use devm_backlight_device_register() to make cleanup paths simpler. Signed-off-by: Jingoo Han Cc: Tomi Valkeinen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/ot200_bl.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/ot200_bl.c b/drivers/video/backlight/ot200_bl.c index fdbb6ee5027c..f5a5202dd79d 100644 --- a/drivers/video/backlight/ot200_bl.c +++ b/drivers/video/backlight/ot200_bl.c @@ -118,8 +118,9 @@ static int ot200_backlight_probe(struct platform_device *pdev) props.brightness = 100; props.type = BACKLIGHT_RAW; - bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, data, - &ot200_backlight_ops, &props); + bl = devm_backlight_device_register(&pdev->dev, dev_name(&pdev->dev), + &pdev->dev, data, &ot200_backlight_ops, + &props); if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); retval = PTR_ERR(bl); @@ -137,10 +138,6 @@ error_devm_kzalloc: static int ot200_backlight_remove(struct platform_device *pdev) { - struct backlight_device *bl = platform_get_drvdata(pdev); - - backlight_device_unregister(bl); - /* on module unload set brightness to 100% */ cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0); cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); -- cgit v1.2.3 From ffb1f6c83b273f2b7aac207ad2220c28d3cfa44a Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Jan 2014 15:54:28 -0800 Subject: backlight: tosa: use devm_backlight_device_register() Use devm_backlight_device_register() to make cleanup paths simpler. Signed-off-by: Jingoo Han Cc: Tomi Valkeinen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/tosa_bl.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c index b8db9338cacd..3ad676558c80 100644 --- a/drivers/video/backlight/tosa_bl.c +++ b/drivers/video/backlight/tosa_bl.c @@ -105,8 +105,9 @@ static int tosa_bl_probe(struct i2c_client *client, memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; props.max_brightness = 512 - 1; - data->bl = backlight_device_register("tosa-bl", &client->dev, data, - &bl_ops, &props); + data->bl = devm_backlight_device_register(&client->dev, "tosa-bl", + &client->dev, data, &bl_ops, + &props); if (IS_ERR(data->bl)) { ret = PTR_ERR(data->bl); goto err_reg; @@ -128,9 +129,7 @@ static int tosa_bl_remove(struct i2c_client *client) { struct tosa_bl_data *data = i2c_get_clientdata(client); - backlight_device_unregister(data->bl); data->bl = NULL; - return 0; } -- cgit v1.2.3 From 964598f239c37cd6df73d94458beaabec3dc6928 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Jan 2014 15:54:29 -0800 Subject: backlight: jornada720: use devm_lcd_device_register() Use devm_lcd_device_register() to make cleanup paths simpler, and remove unnecessary remove(). Signed-off-by: Jingoo Han Cc: Tomi Valkeinen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/jornada720_lcd.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/jornada720_lcd.c b/drivers/video/backlight/jornada720_lcd.c index b061413f1a65..da3876c9b3ae 100644 --- a/drivers/video/backlight/jornada720_lcd.c +++ b/drivers/video/backlight/jornada720_lcd.c @@ -100,7 +100,8 @@ static int jornada_lcd_probe(struct platform_device *pdev) struct lcd_device *lcd_device; int ret; - lcd_device = lcd_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_lcd_props); + lcd_device = devm_lcd_device_register(&pdev->dev, S1D_DEVICENAME, + &pdev->dev, NULL, &jornada_lcd_props); if (IS_ERR(lcd_device)) { ret = PTR_ERR(lcd_device); @@ -119,18 +120,8 @@ static int jornada_lcd_probe(struct platform_device *pdev) return 0; } -static int jornada_lcd_remove(struct platform_device *pdev) -{ - struct lcd_device *lcd_device = platform_get_drvdata(pdev); - - lcd_device_unregister(lcd_device); - - return 0; -} - static struct platform_driver jornada_lcd_driver = { .probe = jornada_lcd_probe, - .remove = jornada_lcd_remove, .driver = { .name = "jornada_lcd", }, -- cgit v1.2.3 From 7dd78077369ebe7db031d9de1d6b4c766b3b4f7d Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Jan 2014 15:54:30 -0800 Subject: backlight: l4f00242t03: use devm_lcd_device_register() Use devm_lcd_device_register() to make cleanup paths simpler. Signed-off-by: Jingoo Han Cc: Tomi Valkeinen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/l4f00242t03.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c index b5fc13bc24e7..63e763828e0e 100644 --- a/drivers/video/backlight/l4f00242t03.c +++ b/drivers/video/backlight/l4f00242t03.c @@ -223,8 +223,8 @@ static int l4f00242t03_probe(struct spi_device *spi) return PTR_ERR(priv->core_reg); } - priv->ld = lcd_device_register("l4f00242t03", - &spi->dev, priv, &l4f_ops); + priv->ld = devm_lcd_device_register(&spi->dev, "l4f00242t03", &spi->dev, + priv, &l4f_ops); if (IS_ERR(priv->ld)) return PTR_ERR(priv->ld); @@ -243,8 +243,6 @@ static int l4f00242t03_remove(struct spi_device *spi) struct l4f00242t03_priv *priv = spi_get_drvdata(spi); l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN); - lcd_device_unregister(priv->ld); - return 0; } -- cgit v1.2.3 From 0f53449d69b99f0455ecd3e3a73a38aa7555b174 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Jan 2014 15:54:30 -0800 Subject: backlight: tosa: use devm_lcd_device_register() Use devm_lcd_device_register() to make cleanup paths simpler. Signed-off-by: Jingoo Han Cc: Tomi Valkeinen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/tosa_lcd.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c index be5d636764bf..f08d641ccd01 100644 --- a/drivers/video/backlight/tosa_lcd.c +++ b/drivers/video/backlight/tosa_lcd.c @@ -206,8 +206,8 @@ static int tosa_lcd_probe(struct spi_device *spi) tosa_lcd_tg_on(data); - data->lcd = lcd_device_register("tosa-lcd", &spi->dev, data, - &tosa_lcd_ops); + data->lcd = devm_lcd_device_register(&spi->dev, "tosa-lcd", &spi->dev, + data, &tosa_lcd_ops); if (IS_ERR(data->lcd)) { ret = PTR_ERR(data->lcd); @@ -226,8 +226,6 @@ static int tosa_lcd_remove(struct spi_device *spi) { struct tosa_lcd_data *data = spi_get_drvdata(spi); - lcd_device_unregister(data->lcd); - if (data->i2c) i2c_unregister_device(data->i2c); -- cgit v1.2.3 From 81f5cdc1b2a48d466bc53f38e843a7981a4e5e0c Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Jan 2014 15:54:31 -0800 Subject: backlight: kb3886_bl: fix incorrect placement of __initdata marker The __initdata marker can be virtually anywhere on the line, EXCEPT right after "struct". The preferred location is before the "=" sign if there is one, or before the trailing ";" otherwise. It also fixes the following chechpatch warning. WARNING: __initdata should be placed after kb3886bl_device_table[] Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/kb3886_bl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c index 7592cc25c963..84a110a719cb 100644 --- a/drivers/video/backlight/kb3886_bl.c +++ b/drivers/video/backlight/kb3886_bl.c @@ -78,7 +78,7 @@ static struct kb3886bl_machinfo *bl_machinfo; static unsigned long kb3886bl_flags; #define KB3886BL_SUSPENDED 0x01 -static struct dmi_system_id __initdata kb3886bl_device_table[] = { +static struct dmi_system_id kb3886bl_device_table[] __initdata = { { .ident = "Sahara Touch-iT", .matches = { -- cgit v1.2.3 From 2ce2386072854f25f03052f819d5fd11ddc75f6c Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Jan 2014 15:54:32 -0800 Subject: backlight: lp855x: remove unnecessary parentheses Remove unnecessary parentheses in order to fix the following checkpatch error. ERROR: return is not a function, parentheses are not required Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/lp855x_bl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c index cae80d555e84..2ca3a040007b 100644 --- a/drivers/video/backlight/lp855x_bl.c +++ b/drivers/video/backlight/lp855x_bl.c @@ -125,7 +125,7 @@ static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr) return false; } - return (addr >= start && addr <= end); + return addr >= start && addr <= end; } static int lp8557_bl_off(struct lp855x *lp) -- cgit v1.2.3 From 68585c41c9863688bff81fd69e37a2f585d474f9 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Jan 2014 15:54:33 -0800 Subject: backlight: lp8788: remove unnecessary parentheses Remove unnecessary parentheses in order to fix the following checkpatch error. ERROR: return is not a function, parentheses are not required Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/lp8788_bl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/lp8788_bl.c b/drivers/video/backlight/lp8788_bl.c index e49905d495dc..daba34dc46d4 100644 --- a/drivers/video/backlight/lp8788_bl.c +++ b/drivers/video/backlight/lp8788_bl.c @@ -63,13 +63,13 @@ static struct lp8788_bl_config default_bl_config = { static inline bool is_brightness_ctrl_by_pwm(enum lp8788_bl_ctrl_mode mode) { - return (mode == LP8788_BL_COMB_PWM_BASED); + return mode == LP8788_BL_COMB_PWM_BASED; } static inline bool is_brightness_ctrl_by_register(enum lp8788_bl_ctrl_mode mode) { - return (mode == LP8788_BL_REGISTER_ONLY || - mode == LP8788_BL_COMB_REGISTER_BASED); + return mode == LP8788_BL_REGISTER_ONLY || + mode == LP8788_BL_COMB_REGISTER_BASED; } static int lp8788_backlight_configure(struct lp8788_bl *bl) -- cgit v1.2.3 From cf0744021c5d5de54d2c66e2020c6de2fe800264 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 23 Jan 2014 15:54:39 -0800 Subject: firmware/dmi_scan: generalize for use by other archs This patch makes a couple of changes to the SMBIOS/DMI scanning code so it can be used on other archs (such as ARM and arm64): (a) wrap the calls to ioremap()/iounmap(), this allows the use of a flavor of ioremap() more suitable for random unaligned access; (b) allow the non-EFI fallback probe into hardcoded physical address 0xF0000 to be disabled. Signed-off-by: Ard Biesheuvel Acked-by: Grant Likely Cc: Ingo Molnar Cc "Luck, Tony" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/Kconfig | 1 + arch/ia64/include/asm/dmi.h | 8 +++++--- arch/x86/Kconfig | 1 + arch/x86/include/asm/dmi.h | 6 ++++-- drivers/firmware/Kconfig | 3 +++ drivers/firmware/dmi_scan.c | 20 ++++++++++---------- 6 files changed, 24 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index a8c3a11dc5ab..c063b054294e 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -104,6 +104,7 @@ config HAVE_SETUP_PER_CPU_AREA config DMI bool default y + select DMI_SCAN_MACHINE_NON_EFI_FALLBACK config EFI bool diff --git a/arch/ia64/include/asm/dmi.h b/arch/ia64/include/asm/dmi.h index 185d3d18d0ec..f365a61f5c71 100644 --- a/arch/ia64/include/asm/dmi.h +++ b/arch/ia64/include/asm/dmi.h @@ -5,8 +5,10 @@ #include /* Use normal IO mappings for DMI */ -#define dmi_ioremap ioremap -#define dmi_iounmap(x,l) iounmap(x) -#define dmi_alloc(l) kzalloc(l, GFP_ATOMIC) +#define dmi_early_remap ioremap +#define dmi_early_unmap(x, l) iounmap(x) +#define dmi_remap ioremap +#define dmi_unmap iounmap +#define dmi_alloc(l) kzalloc(l, GFP_ATOMIC) #endif diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index d3b9186e4c23..5aadc49a7621 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -731,6 +731,7 @@ config APB_TIMER # The code disables itself when not needed. config DMI default y + select DMI_SCAN_MACHINE_NON_EFI_FALLBACK bool "Enable DMI scanning" if EXPERT ---help--- Enabled scanning of DMI to identify machine quirks. Say Y diff --git a/arch/x86/include/asm/dmi.h b/arch/x86/include/asm/dmi.h index fd8f9e2ca35f..535192f6bfad 100644 --- a/arch/x86/include/asm/dmi.h +++ b/arch/x86/include/asm/dmi.h @@ -13,7 +13,9 @@ static __always_inline __init void *dmi_alloc(unsigned len) } /* Use early IO mappings for DMI because it's initialized early */ -#define dmi_ioremap early_ioremap -#define dmi_iounmap early_iounmap +#define dmi_early_remap early_ioremap +#define dmi_early_unmap early_iounmap +#define dmi_remap ioremap +#define dmi_unmap iounmap #endif /* _ASM_X86_DMI_H */ diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 074787281c94..5a29fac951ec 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -108,6 +108,9 @@ config DMI_SYSFS under /sys/firmware/dmi when this option is enabled and loaded. +config DMI_SCAN_MACHINE_NON_EFI_FALLBACK + bool + config ISCSI_IBFT_FIND bool "iSCSI Boot Firmware Table Attributes" depends on X86 diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index c7e81ff8f3ef..17afc51f3054 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -116,7 +116,7 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *, { u8 *buf; - buf = dmi_ioremap(dmi_base, dmi_len); + buf = dmi_early_remap(dmi_base, dmi_len); if (buf == NULL) return -1; @@ -124,7 +124,7 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *, add_device_randomness(buf, dmi_len); - dmi_iounmap(buf, dmi_len); + dmi_early_unmap(buf, dmi_len); return 0; } @@ -527,18 +527,18 @@ void __init dmi_scan_machine(void) * needed during early boot. This also means we can * iounmap the space when we're done with it. */ - p = dmi_ioremap(efi.smbios, 32); + p = dmi_early_remap(efi.smbios, 32); if (p == NULL) goto error; memcpy_fromio(buf, p, 32); - dmi_iounmap(p, 32); + dmi_early_unmap(p, 32); if (!dmi_present(buf)) { dmi_available = 1; goto out; } - } else { - p = dmi_ioremap(0xF0000, 0x10000); + } else if (IS_ENABLED(CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK)) { + p = dmi_early_remap(0xF0000, 0x10000); if (p == NULL) goto error; @@ -554,12 +554,12 @@ void __init dmi_scan_machine(void) memcpy_fromio(buf + 16, q, 16); if (!dmi_present(buf)) { dmi_available = 1; - dmi_iounmap(p, 0x10000); + dmi_early_unmap(p, 0x10000); goto out; } memcpy(buf, buf + 16, 16); } - dmi_iounmap(p, 0x10000); + dmi_early_unmap(p, 0x10000); } error: pr_info("DMI not present or invalid.\n"); @@ -831,13 +831,13 @@ int dmi_walk(void (*decode)(const struct dmi_header *, void *), if (!dmi_available) return -1; - buf = ioremap(dmi_base, dmi_len); + buf = dmi_remap(dmi_base, dmi_len); if (buf == NULL) return -1; dmi_table(buf, dmi_len, dmi_num, decode, private_data); - iounmap(buf); + dmi_unmap(buf); return 0; } EXPORT_SYMBOL_GPL(dmi_walk); -- cgit v1.2.3 From 75465c49f092f24acc236b0f51e9b8bf8adc329e Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Thu, 23 Jan 2014 15:55:02 -0800 Subject: drivers/rtc/rtc-as3722: use devm for rtc and irq registration Use devm_* calls for rtc and irq registration and get rid of remove callback for platform driver. Signed-off-by: Laxman Dewangan Cc: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-as3722.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-as3722.c b/drivers/rtc/rtc-as3722.c index 9cfa8170a2d6..4af016985890 100644 --- a/drivers/rtc/rtc-as3722.c +++ b/drivers/rtc/rtc-as3722.c @@ -198,7 +198,7 @@ static int as3722_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); - as3722_rtc->rtc = rtc_device_register("as3722", &pdev->dev, + as3722_rtc->rtc = devm_rtc_device_register(&pdev->dev, "as3722-rtc", &as3722_rtc_ops, THIS_MODULE); if (IS_ERR(as3722_rtc->rtc)) { ret = PTR_ERR(as3722_rtc->rtc); @@ -209,28 +209,16 @@ static int as3722_rtc_probe(struct platform_device *pdev) as3722_rtc->alarm_irq = platform_get_irq(pdev, 0); dev_info(&pdev->dev, "RTC interrupt %d\n", as3722_rtc->alarm_irq); - ret = request_threaded_irq(as3722_rtc->alarm_irq, NULL, + ret = devm_request_threaded_irq(&pdev->dev, as3722_rtc->alarm_irq, NULL, as3722_alarm_irq, IRQF_ONESHOT | IRQF_EARLY_RESUME, "rtc-alarm", as3722_rtc); if (ret < 0) { dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", as3722_rtc->alarm_irq, ret); - goto scrub; + return ret; } disable_irq(as3722_rtc->alarm_irq); return 0; -scrub: - rtc_device_unregister(as3722_rtc->rtc); - return ret; -} - -static int as3722_rtc_remove(struct platform_device *pdev) -{ - struct as3722_rtc *as3722_rtc = platform_get_drvdata(pdev); - - free_irq(as3722_rtc->alarm_irq, as3722_rtc); - rtc_device_unregister(as3722_rtc->rtc); - return 0; } #ifdef CONFIG_PM_SLEEP @@ -260,7 +248,6 @@ static const struct dev_pm_ops as3722_rtc_pm_ops = { static struct platform_driver as3722_rtc_driver = { .probe = as3722_rtc_probe, - .remove = as3722_rtc_remove, .driver = { .name = "as3722-rtc", .pm = &as3722_rtc_pm_ops, -- cgit v1.2.3 From a3e6ad6740c6e77beda83d4238f2123bf3aef45f Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Jan 2014 15:55:03 -0800 Subject: drivers/rtc/rtc-ds1305.c: remove unnecessary spi_set_drvdata() The driver core clears the driver data to NULL after device_release or on probe failure. Thus, it is not needed to manually clear the device driver data to NULL. Signed-off-by: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1305.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 80f323731ee2..2dd586a19b59 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -787,7 +787,6 @@ static int ds1305_remove(struct spi_device *spi) cancel_work_sync(&ds1305->work); } - spi_set_drvdata(spi, NULL); return 0; } -- cgit v1.2.3 From fbd5e754cb03c134ed45ff3417606daf61f576ca Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 23 Jan 2014 15:55:04 -0800 Subject: drivers/rtc/rtc-mxc.c: remove unneeded label There is no need to jump to the 'exit_free_pdata' label when devm_clk_get() fails, as we can directly return the error and simplify the code a bit. Signed-off-by: Fabio Estevam Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-mxc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 50c572645546..a3ed1cf935ba 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -391,8 +391,7 @@ static int mxc_rtc_probe(struct platform_device *pdev) pdata->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(pdata->clk)) { dev_err(&pdev->dev, "unable to get clock!\n"); - ret = PTR_ERR(pdata->clk); - goto exit_free_pdata; + return PTR_ERR(pdata->clk); } clk_prepare_enable(pdata->clk); @@ -447,8 +446,6 @@ static int mxc_rtc_probe(struct platform_device *pdev) exit_put_clk: clk_disable_unprepare(pdata->clk); -exit_free_pdata: - return ret; } -- cgit v1.2.3 From 1b3d2243d049e062d0dc53b85f0e95db67e114af Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 23 Jan 2014 15:55:05 -0800 Subject: drivers/rtc/rtc-mxc.c: check the return value from clk_prepare_enable() clk_prepare_enable() may fail, so let's check its return value and propagate it in the case of error. Signed-off-by: Fabio Estevam Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-mxc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index a3ed1cf935ba..419874fefa4b 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -394,7 +394,10 @@ static int mxc_rtc_probe(struct platform_device *pdev) return PTR_ERR(pdata->clk); } - clk_prepare_enable(pdata->clk); + ret = clk_prepare_enable(pdata->clk); + if (ret) + return ret; + rate = clk_get_rate(pdata->clk); if (rate == 32768) -- cgit v1.2.3 From 663b35241df1d0ed24be3d17733807cc8723cc4a Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Thu, 23 Jan 2014 15:55:06 -0800 Subject: drivers/rtc/rtc-ds1742.c: add devicetree support This patch allows the driver to be enabled with devicetree. Signed-off-by: Alexander Shiyan Acked-by: Mark Rutland Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/devicetree/bindings/rtc/maxim,ds1742.txt | 12 ++++++++++++ drivers/rtc/rtc-ds1742.c | 10 +++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/rtc/maxim,ds1742.txt (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/rtc/maxim,ds1742.txt b/Documentation/devicetree/bindings/rtc/maxim,ds1742.txt new file mode 100644 index 000000000000..d0f937c355b5 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/maxim,ds1742.txt @@ -0,0 +1,12 @@ +* Maxim (Dallas) DS1742/DS1743 Real Time Clock + +Required properties: +- compatible: Should contain "maxim,ds1742". +- reg: Physical base address of the RTC and length of memory + mapped region. + +Example: + rtc: rtc@10000000 { + compatible = "maxim,ds1742"; + reg = <0x10000000 0x800>; + }; diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 17b73fdc3b6e..d7f74f5e9090 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -13,12 +13,13 @@ */ #include -#include #include #include #include #include #include +#include +#include #include #include #include @@ -215,12 +216,19 @@ static int ds1742_rtc_remove(struct platform_device *pdev) return 0; } +static struct of_device_id __maybe_unused ds1742_rtc_of_match[] = { + { .compatible = "maxim,ds1742", }, + { } +}; +MODULE_DEVICE_TABLE(of, ds1742_rtc_of_match); + static struct platform_driver ds1742_rtc_driver = { .probe = ds1742_rtc_probe, .remove = ds1742_rtc_remove, .driver = { .name = "rtc-ds1742", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(ds1742_rtc_of_match), }, }; -- cgit v1.2.3 From f53eeb853dfe408737ac6b8c3117bd21a9c60fd4 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Jan 2014 15:55:06 -0800 Subject: drivers/rtc/rtc-twl.c: use devm_*() functions Use devm_*() functions to make cleanup paths simpler, and remove unnecessary remove(). Signed-off-by: Jingoo Han Cc: Yoichi Yuasa Cc: Grygorii Strashko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-twl.c | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index c2e80d7ca5e2..1915464e4cd6 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -479,7 +479,7 @@ static int twl_rtc_probe(struct platform_device *pdev) u8 rd_reg; if (irq <= 0) - goto out1; + return ret; /* Initialize the register map */ if (twl_class_is_4030()) @@ -489,7 +489,7 @@ static int twl_rtc_probe(struct platform_device *pdev) ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); if (ret < 0) - goto out1; + return ret; if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M) dev_warn(&pdev->dev, "Power up reset detected.\n"); @@ -500,7 +500,7 @@ static int twl_rtc_probe(struct platform_device *pdev) /* Clear RTC Power up reset and pending alarm interrupts */ ret = twl_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG); if (ret < 0) - goto out1; + return ret; if (twl_class_is_6030()) { twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK, @@ -512,7 +512,7 @@ static int twl_rtc_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Enabling TWL-RTC\n"); ret = twl_rtc_write_u8(BIT_RTC_CTRL_REG_STOP_RTC_M, REG_RTC_CTRL_REG); if (ret < 0) - goto out1; + return ret; /* ensure interrupts are disabled, bootloaders can be strange */ ret = twl_rtc_write_u8(0, REG_RTC_INTERRUPTS_REG); @@ -522,34 +522,29 @@ static int twl_rtc_probe(struct platform_device *pdev) /* init cached IRQ enable bits */ ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); if (ret < 0) - goto out1; + return ret; device_init_wakeup(&pdev->dev, 1); - rtc = rtc_device_register(pdev->name, - &pdev->dev, &twl_rtc_ops, THIS_MODULE); + rtc = devm_rtc_device_register(&pdev->dev, pdev->name, + &twl_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { - ret = PTR_ERR(rtc); dev_err(&pdev->dev, "can't register RTC device, err %ld\n", PTR_ERR(rtc)); - goto out1; + return PTR_ERR(rtc); } - ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, - dev_name(&rtc->dev), rtc); + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, + twl_rtc_interrupt, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + dev_name(&rtc->dev), rtc); if (ret < 0) { dev_err(&pdev->dev, "IRQ is not free.\n"); - goto out2; + return ret; } platform_set_drvdata(pdev, rtc); return 0; - -out2: - rtc_device_unregister(rtc); -out1: - return ret; } /* @@ -559,9 +554,6 @@ out1: static int twl_rtc_remove(struct platform_device *pdev) { /* leave rtc running, but disable irqs */ - struct rtc_device *rtc = platform_get_drvdata(pdev); - int irq = platform_get_irq(pdev, 0); - mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M); mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M); if (twl_class_is_6030()) { @@ -571,10 +563,6 @@ static int twl_rtc_remove(struct platform_device *pdev) REG_INT_MSK_STS_A); } - - free_irq(irq, rtc); - - rtc_device_unregister(rtc); return 0; } -- cgit v1.2.3 From bf6ce1a102797ceca6d44de991def4e0c1825cb2 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 Jan 2014 15:55:07 -0800 Subject: drivers/rtc/rtc-vr41xx.c: use devm_*() functions Use devm_*() functions to make cleanup paths simpler, and remove unnecessary remove(). Signed-off-by: Jingoo Han Cc: Yoichi Yuasa Cc: Grygorii Strashko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-vr41xx.c | 50 ++++++++++++------------------------------------ 1 file changed, 12 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index aabc22c587fb..88c9c92e89fd 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c @@ -293,7 +293,7 @@ static int rtc_probe(struct platform_device *pdev) if (!res) return -EBUSY; - rtc1_base = ioremap(res->start, resource_size(res)); + rtc1_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!rtc1_base) return -EBUSY; @@ -303,13 +303,14 @@ static int rtc_probe(struct platform_device *pdev) goto err_rtc1_iounmap; } - rtc2_base = ioremap(res->start, resource_size(res)); + rtc2_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!rtc2_base) { retval = -EBUSY; goto err_rtc1_iounmap; } - rtc = rtc_device_register(rtc_name, &pdev->dev, &vr41xx_rtc_ops, THIS_MODULE); + rtc = devm_rtc_device_register(&pdev->dev, rtc_name, &vr41xx_rtc_ops, + THIS_MODULE); if (IS_ERR(rtc)) { retval = PTR_ERR(rtc); goto err_iounmap_all; @@ -330,24 +331,24 @@ static int rtc_probe(struct platform_device *pdev) aie_irq = platform_get_irq(pdev, 0); if (aie_irq <= 0) { retval = -EBUSY; - goto err_device_unregister; + goto err_iounmap_all; } - retval = request_irq(aie_irq, elapsedtime_interrupt, 0, - "elapsed_time", pdev); + retval = devm_request_irq(&pdev->dev, aie_irq, elapsedtime_interrupt, 0, + "elapsed_time", pdev); if (retval < 0) - goto err_device_unregister; + goto err_iounmap_all; pie_irq = platform_get_irq(pdev, 1); if (pie_irq <= 0) { retval = -EBUSY; - goto err_free_irq; + goto err_iounmap_all; } - retval = request_irq(pie_irq, rtclong1_interrupt, 0, - "rtclong1", pdev); + retval = devm_request_irq(&pdev->dev, pie_irq, rtclong1_interrupt, 0, + "rtclong1", pdev); if (retval < 0) - goto err_free_irq; + goto err_iounmap_all; platform_set_drvdata(pdev, rtc); @@ -358,47 +359,20 @@ static int rtc_probe(struct platform_device *pdev) return 0; -err_free_irq: - free_irq(aie_irq, pdev); - -err_device_unregister: - rtc_device_unregister(rtc); - err_iounmap_all: - iounmap(rtc2_base); rtc2_base = NULL; err_rtc1_iounmap: - iounmap(rtc1_base); rtc1_base = NULL; return retval; } -static int rtc_remove(struct platform_device *pdev) -{ - struct rtc_device *rtc; - - rtc = platform_get_drvdata(pdev); - if (rtc) - rtc_device_unregister(rtc); - - free_irq(aie_irq, pdev); - free_irq(pie_irq, pdev); - if (rtc1_base) - iounmap(rtc1_base); - if (rtc2_base) - iounmap(rtc2_base); - - return 0; -} - /* work with hotplug and coldplug */ MODULE_ALIAS("platform:RTC"); static struct platform_driver rtc_platform_driver = { .probe = rtc_probe, - .remove = rtc_remove, .driver = { .name = rtc_name, .owner = THIS_MODULE, -- cgit v1.2.3 From dcaf038493525604e3d1648d5761a852e8db2bf9 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 23 Jan 2014 15:55:10 -0800 Subject: rtc: add hym8563 rtc-driver The Haoyu Microelectronics HYM8563 provides rtc and alarm functions as well as a clock output of up to 32kHz. Signed-off-by: Heiko Stuebner Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Stephen Warren Cc: Ian Campbell Cc: Grant Likely Cc: Mike Turquette Cc: Richard Weinberger Cc: Mark Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/Kconfig | 11 + drivers/rtc/Makefile | 1 + drivers/rtc/rtc-hym8563.c | 606 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 618 insertions(+) create mode 100644 drivers/rtc/rtc-hym8563.c (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 007730222116..4bd489c67e5e 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -212,6 +212,17 @@ config RTC_DRV_DS3232 This driver can also be built as a module. If so, the module will be called rtc-ds3232. +config RTC_DRV_HYM8563 + tristate "Haoyu Microelectronics HYM8563" + depends on I2C && OF + help + Say Y to enable support for the HYM8563 I2C RTC chip. Apart + from the usual rtc functions it provides a clock output of + up to 32kHz. + + This driver can also be built as a module. If so, the module + will be called rtc-hym8563. + config RTC_DRV_LP8788 tristate "TI LP8788 RTC driver" depends on MFD_LP8788 diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 27b4bd884066..913c5bed0154 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o +obj-$(CONFIG_RTC_DRV_HYM8563) += rtc-hym8563.o obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c new file mode 100644 index 000000000000..b56e3d3fbfd3 --- /dev/null +++ b/drivers/rtc/rtc-hym8563.c @@ -0,0 +1,606 @@ +/* + * Haoyu HYM8563 RTC driver + * + * Copyright (C) 2013 MundoReader S.L. + * Author: Heiko Stuebner + * + * based on rtc-HYM8563 + * Copyright (C) 2010 ROCKCHIP, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#define HYM8563_CTL1 0x00 +#define HYM8563_CTL1_TEST BIT(7) +#define HYM8563_CTL1_STOP BIT(5) +#define HYM8563_CTL1_TESTC BIT(3) + +#define HYM8563_CTL2 0x01 +#define HYM8563_CTL2_TI_TP BIT(4) +#define HYM8563_CTL2_AF BIT(3) +#define HYM8563_CTL2_TF BIT(2) +#define HYM8563_CTL2_AIE BIT(1) +#define HYM8563_CTL2_TIE BIT(0) + +#define HYM8563_SEC 0x02 +#define HYM8563_SEC_VL BIT(7) +#define HYM8563_SEC_MASK 0x7f + +#define HYM8563_MIN 0x03 +#define HYM8563_MIN_MASK 0x7f + +#define HYM8563_HOUR 0x04 +#define HYM8563_HOUR_MASK 0x3f + +#define HYM8563_DAY 0x05 +#define HYM8563_DAY_MASK 0x3f + +#define HYM8563_WEEKDAY 0x06 +#define HYM8563_WEEKDAY_MASK 0x07 + +#define HYM8563_MONTH 0x07 +#define HYM8563_MONTH_CENTURY BIT(7) +#define HYM8563_MONTH_MASK 0x1f + +#define HYM8563_YEAR 0x08 + +#define HYM8563_ALM_MIN 0x09 +#define HYM8563_ALM_HOUR 0x0a +#define HYM8563_ALM_DAY 0x0b +#define HYM8563_ALM_WEEK 0x0c + +/* Each alarm check can be disabled by setting this bit in the register */ +#define HYM8563_ALM_BIT_DISABLE BIT(7) + +#define HYM8563_CLKOUT 0x0d +#define HYM8563_CLKOUT_DISABLE BIT(7) +#define HYM8563_CLKOUT_32768 0 +#define HYM8563_CLKOUT_1024 1 +#define HYM8563_CLKOUT_32 2 +#define HYM8563_CLKOUT_1 3 +#define HYM8563_CLKOUT_MASK 3 + +#define HYM8563_TMR_CTL 0x0e +#define HYM8563_TMR_CTL_ENABLE BIT(7) +#define HYM8563_TMR_CTL_4096 0 +#define HYM8563_TMR_CTL_64 1 +#define HYM8563_TMR_CTL_1 2 +#define HYM8563_TMR_CTL_1_60 3 +#define HYM8563_TMR_CTL_MASK 3 + +#define HYM8563_TMR_CNT 0x0f + +struct hym8563 { + struct i2c_client *client; + struct rtc_device *rtc; + bool valid; +#ifdef CONFIG_COMMON_CLK + struct clk_hw clkout_hw; +#endif +}; + +/* + * RTC handling + */ + +static int hym8563_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct i2c_client *client = to_i2c_client(dev); + struct hym8563 *hym8563 = i2c_get_clientdata(client); + u8 buf[7]; + int ret; + + if (!hym8563->valid) { + dev_warn(&client->dev, "no valid clock/calendar values available\n"); + return -EPERM; + } + + ret = i2c_smbus_read_i2c_block_data(client, HYM8563_SEC, 7, buf); + + tm->tm_sec = bcd2bin(buf[0] & HYM8563_SEC_MASK); + tm->tm_min = bcd2bin(buf[1] & HYM8563_MIN_MASK); + tm->tm_hour = bcd2bin(buf[2] & HYM8563_HOUR_MASK); + tm->tm_mday = bcd2bin(buf[3] & HYM8563_DAY_MASK); + tm->tm_wday = bcd2bin(buf[4] & HYM8563_WEEKDAY_MASK); /* 0 = Sun */ + tm->tm_mon = bcd2bin(buf[5] & HYM8563_MONTH_MASK) - 1; /* 0 = Jan */ + tm->tm_year = bcd2bin(buf[6]) + 100; + + return 0; +} + +static int hym8563_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct i2c_client *client = to_i2c_client(dev); + struct hym8563 *hym8563 = i2c_get_clientdata(client); + u8 buf[7]; + int ret; + + /* Years >= 2100 are to far in the future, 19XX is to early */ + if (tm->tm_year < 100 || tm->tm_year >= 200) + return -EINVAL; + + buf[0] = bin2bcd(tm->tm_sec); + buf[1] = bin2bcd(tm->tm_min); + buf[2] = bin2bcd(tm->tm_hour); + buf[3] = bin2bcd(tm->tm_mday); + buf[4] = bin2bcd(tm->tm_wday); + buf[5] = bin2bcd(tm->tm_mon + 1); + + /* + * While the HYM8563 has a century flag in the month register, + * it does not seem to carry it over a subsequent write/read. + * So we'll limit ourself to 100 years, starting at 2000 for now. + */ + buf[6] = tm->tm_year - 100; + + /* + * CTL1 only contains TEST-mode bits apart from stop, + * so no need to read the value first + */ + ret = i2c_smbus_write_byte_data(client, HYM8563_CTL1, + HYM8563_CTL1_STOP); + if (ret < 0) + return ret; + + ret = i2c_smbus_write_i2c_block_data(client, HYM8563_SEC, 7, buf); + if (ret < 0) + return ret; + + ret = i2c_smbus_write_byte_data(client, HYM8563_CTL1, 0); + if (ret < 0) + return ret; + + hym8563->valid = true; + + return 0; +} + +static int hym8563_rtc_alarm_irq_enable(struct device *dev, + unsigned int enabled) +{ + struct i2c_client *client = to_i2c_client(dev); + int data; + + data = i2c_smbus_read_byte_data(client, HYM8563_CTL2); + if (data < 0) + return data; + + if (enabled) + data |= HYM8563_CTL2_AIE; + else + data &= ~HYM8563_CTL2_AIE; + + return i2c_smbus_write_byte_data(client, HYM8563_CTL2, data); +}; + +static int hym8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + struct i2c_client *client = to_i2c_client(dev); + struct rtc_time *alm_tm = &alm->time; + u8 buf[4]; + int ret; + + ret = i2c_smbus_read_i2c_block_data(client, HYM8563_ALM_MIN, 4, buf); + if (ret < 0) + return ret; + + /* The alarm only has a minute accuracy */ + alm_tm->tm_sec = -1; + + alm_tm->tm_min = (buf[0] & HYM8563_ALM_BIT_DISABLE) ? + -1 : + bcd2bin(buf[0] & HYM8563_MIN_MASK); + alm_tm->tm_hour = (buf[1] & HYM8563_ALM_BIT_DISABLE) ? + -1 : + bcd2bin(buf[1] & HYM8563_HOUR_MASK); + alm_tm->tm_mday = (buf[2] & HYM8563_ALM_BIT_DISABLE) ? + -1 : + bcd2bin(buf[2] & HYM8563_DAY_MASK); + alm_tm->tm_wday = (buf[3] & HYM8563_ALM_BIT_DISABLE) ? + -1 : + bcd2bin(buf[3] & HYM8563_WEEKDAY_MASK); + + alm_tm->tm_mon = -1; + alm_tm->tm_year = -1; + + ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2); + if (ret < 0) + return ret; + + if (ret & HYM8563_CTL2_AIE) + alm->enabled = 1; + + return 0; +} + +static int hym8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + struct i2c_client *client = to_i2c_client(dev); + struct rtc_time *alm_tm = &alm->time; + u8 buf[4]; + int ret; + + /* + * The alarm has no seconds so deal with it + */ + if (alm_tm->tm_sec) { + alm_tm->tm_sec = 0; + alm_tm->tm_min++; + if (alm_tm->tm_min >= 60) { + alm_tm->tm_min = 0; + alm_tm->tm_hour++; + if (alm_tm->tm_hour >= 24) { + alm_tm->tm_hour = 0; + alm_tm->tm_mday++; + if (alm_tm->tm_mday > 31) + alm_tm->tm_mday = 0; + } + } + } + + ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2); + if (ret < 0) + return ret; + + ret &= ~HYM8563_CTL2_AIE; + + ret = i2c_smbus_write_byte_data(client, HYM8563_CTL2, ret); + if (ret < 0) + return ret; + + buf[0] = (alm_tm->tm_min < 60 && alm_tm->tm_min >= 0) ? + bin2bcd(alm_tm->tm_min) : HYM8563_ALM_BIT_DISABLE; + + buf[1] = (alm_tm->tm_hour < 24 && alm_tm->tm_hour >= 0) ? + bin2bcd(alm_tm->tm_hour) : HYM8563_ALM_BIT_DISABLE; + + buf[2] = (alm_tm->tm_mday <= 31 && alm_tm->tm_mday >= 1) ? + bin2bcd(alm_tm->tm_mday) : HYM8563_ALM_BIT_DISABLE; + + buf[3] = (alm_tm->tm_wday < 7 && alm_tm->tm_wday >= 0) ? + bin2bcd(alm_tm->tm_wday) : HYM8563_ALM_BIT_DISABLE; + + ret = i2c_smbus_write_i2c_block_data(client, HYM8563_ALM_MIN, 4, buf); + if (ret < 0) + return ret; + + return hym8563_rtc_alarm_irq_enable(dev, alm->enabled); +} + +static const struct rtc_class_ops hym8563_rtc_ops = { + .read_time = hym8563_rtc_read_time, + .set_time = hym8563_rtc_set_time, + .alarm_irq_enable = hym8563_rtc_alarm_irq_enable, + .read_alarm = hym8563_rtc_read_alarm, + .set_alarm = hym8563_rtc_set_alarm, +}; + +/* + * Handling of the clkout + */ + +#ifdef CONFIG_COMMON_CLK +#define clkout_hw_to_hym8563(_hw) container_of(_hw, struct hym8563, clkout_hw) + +static int clkout_rates[] = { + 32768, + 1024, + 32, + 1, +}; + +static unsigned long hym8563_clkout_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct hym8563 *hym8563 = clkout_hw_to_hym8563(hw); + struct i2c_client *client = hym8563->client; + int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT); + + if (ret < 0 || ret & HYM8563_CLKOUT_DISABLE) + return 0; + + ret &= HYM8563_CLKOUT_MASK; + return clkout_rates[ret]; +} + +static long hym8563_clkout_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) + if (clkout_rates[i] <= rate) + return clkout_rates[i]; + + return 0; +} + +static int hym8563_clkout_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct hym8563 *hym8563 = clkout_hw_to_hym8563(hw); + struct i2c_client *client = hym8563->client; + int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT); + int i; + + if (ret < 0) + return ret; + + for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) + if (clkout_rates[i] == rate) { + ret &= ~HYM8563_CLKOUT_MASK; + ret |= i; + return i2c_smbus_write_byte_data(client, + HYM8563_CLKOUT, ret); + } + + return -EINVAL; +} + +static int hym8563_clkout_control(struct clk_hw *hw, bool enable) +{ + struct hym8563 *hym8563 = clkout_hw_to_hym8563(hw); + struct i2c_client *client = hym8563->client; + int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT); + + if (ret < 0) + return ret; + + if (enable) + ret &= ~HYM8563_CLKOUT_DISABLE; + else + ret |= HYM8563_CLKOUT_DISABLE; + + return i2c_smbus_write_byte_data(client, HYM8563_CLKOUT, ret); +} + +static int hym8563_clkout_prepare(struct clk_hw *hw) +{ + return hym8563_clkout_control(hw, 1); +} + +static void hym8563_clkout_unprepare(struct clk_hw *hw) +{ + hym8563_clkout_control(hw, 0); +} + +static int hym8563_clkout_is_prepared(struct clk_hw *hw) +{ + struct hym8563 *hym8563 = clkout_hw_to_hym8563(hw); + struct i2c_client *client = hym8563->client; + int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT); + + if (ret < 0) + return ret; + + return !(ret & HYM8563_CLKOUT_DISABLE); +} + +const struct clk_ops hym8563_clkout_ops = { + .prepare = hym8563_clkout_prepare, + .unprepare = hym8563_clkout_unprepare, + .is_prepared = hym8563_clkout_is_prepared, + .recalc_rate = hym8563_clkout_recalc_rate, + .round_rate = hym8563_clkout_round_rate, + .set_rate = hym8563_clkout_set_rate, +}; + +static struct clk *hym8563_clkout_register_clk(struct hym8563 *hym8563) +{ + struct i2c_client *client = hym8563->client; + struct device_node *node = client->dev.of_node; + struct clk *clk; + struct clk_init_data init; + int ret; + + ret = i2c_smbus_write_byte_data(client, HYM8563_CLKOUT, + HYM8563_CLKOUT_DISABLE); + if (ret < 0) + return ERR_PTR(ret); + + init.name = "hym8563-clkout"; + init.ops = &hym8563_clkout_ops; + init.flags = CLK_IS_ROOT; + init.parent_names = NULL; + init.num_parents = 0; + hym8563->clkout_hw.init = &init; + + /* register the clock */ + clk = clk_register(&client->dev, &hym8563->clkout_hw); + + if (!IS_ERR(clk)) + of_clk_add_provider(node, of_clk_src_simple_get, clk); + + return clk; +} +#endif + +/* + * The alarm interrupt is implemented as a level-low interrupt in the + * hym8563, while the timer interrupt uses a falling edge. + * We don't use the timer at all, so the interrupt is requested to + * use the level-low trigger. + */ +static irqreturn_t hym8563_irq(int irq, void *dev_id) +{ + struct hym8563 *hym8563 = (struct hym8563 *)dev_id; + struct i2c_client *client = hym8563->client; + struct mutex *lock = &hym8563->rtc->ops_lock; + int data, ret; + + mutex_lock(lock); + + /* Clear the alarm flag */ + + data = i2c_smbus_read_byte_data(client, HYM8563_CTL2); + if (data < 0) { + dev_err(&client->dev, "%s: error reading i2c data %d\n", + __func__, data); + goto out; + } + + data &= ~HYM8563_CTL2_AF; + + ret = i2c_smbus_write_byte_data(client, HYM8563_CTL2, data); + if (ret < 0) { + dev_err(&client->dev, "%s: error writing i2c data %d\n", + __func__, ret); + } + +out: + mutex_unlock(lock); + return IRQ_HANDLED; +} + +static int hym8563_init_device(struct i2c_client *client) +{ + int ret; + + /* Clear stop flag if present */ + ret = i2c_smbus_write_byte_data(client, HYM8563_CTL1, 0); + if (ret < 0) + return ret; + + ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2); + if (ret < 0) + return ret; + + /* Disable alarm and timer interrupts */ + ret &= ~HYM8563_CTL2_AIE; + ret &= ~HYM8563_CTL2_TIE; + + /* Clear any pending alarm and timer flags */ + if (ret & HYM8563_CTL2_AF) + ret &= ~HYM8563_CTL2_AF; + + if (ret & HYM8563_CTL2_TF) + ret &= ~HYM8563_CTL2_TF; + + ret &= ~HYM8563_CTL2_TI_TP; + + return i2c_smbus_write_byte_data(client, HYM8563_CTL2, ret); +} + +#ifdef CONFIG_PM_SLEEP +static int hym8563_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + int ret; + + if (device_may_wakeup(dev)) { + ret = enable_irq_wake(client->irq); + if (ret) { + dev_err(dev, "enable_irq_wake failed, %d\n", ret); + return ret; + } + } + + return 0; +} + +static int hym8563_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + + if (device_may_wakeup(dev)) + disable_irq_wake(client->irq); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(hym8563_pm_ops, hym8563_suspend, hym8563_resume); + +static int hym8563_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct hym8563 *hym8563; + int ret; + + hym8563 = devm_kzalloc(&client->dev, sizeof(*hym8563), GFP_KERNEL); + if (!hym8563) + return -ENOMEM; + + hym8563->client = client; + i2c_set_clientdata(client, hym8563); + + device_set_wakeup_capable(&client->dev, true); + + ret = hym8563_init_device(client); + if (ret) { + dev_err(&client->dev, "could not init device, %d\n", ret); + return ret; + } + + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, hym8563_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + client->name, hym8563); + if (ret < 0) { + dev_err(&client->dev, "irq %d request failed, %d\n", + client->irq, ret); + return ret; + } + + /* check state of calendar information */ + ret = i2c_smbus_read_byte_data(client, HYM8563_SEC); + if (ret < 0) + return ret; + + hym8563->valid = !(ret & HYM8563_SEC_VL); + dev_dbg(&client->dev, "rtc information is %s\n", + hym8563->valid ? "valid" : "invalid"); + + hym8563->rtc = devm_rtc_device_register(&client->dev, client->name, + &hym8563_rtc_ops, THIS_MODULE); + if (IS_ERR(hym8563->rtc)) + return PTR_ERR(hym8563->rtc); + +#ifdef CONFIG_COMMON_CLK + hym8563_clkout_register_clk(hym8563); +#endif + + return 0; +} + +static const struct i2c_device_id hym8563_id[] = { + { "hym8563", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, hym8563_id); + +static struct of_device_id hym8563_dt_idtable[] = { + { .compatible = "haoyu,hym8563" }, + {}, +}; +MODULE_DEVICE_TABLE(of, hym8563_dt_idtable); + +static struct i2c_driver hym8563_driver = { + .driver = { + .name = "rtc-hym8563", + .owner = THIS_MODULE, + .pm = &hym8563_pm_ops, + .of_match_table = of_match_ptr(hym8563_dt_idtable), + }, + .probe = hym8563_probe, + .id_table = hym8563_id, +}; + +module_i2c_driver(hym8563_driver); + +MODULE_AUTHOR("Heiko Stuebner "); +MODULE_DESCRIPTION("HYM8563 RTC driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From c823a20244e1673047ac88b4439809748e2ab34e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 23 Jan 2014 15:55:11 -0800 Subject: drivers/rtc/rtc-cmos.c: remove superfluous name cast device_driver.name is "const char *" Signed-off-by: Geert Uytterhoeven Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-cmos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index a2325bc5e497..f28b45856d66 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -1175,7 +1175,7 @@ static struct platform_driver cmos_platform_driver = { .remove = __exit_p(cmos_platform_remove), .shutdown = cmos_platform_shutdown, .driver = { - .name = (char *) driver_name, + .name = driver_name, #ifdef CONFIG_PM .pm = &cmos_pm_ops, #endif -- cgit v1.2.3 From 41c9dbf4ba7cea158cfc1aeb0d6ec3270fb5427b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 23 Jan 2014 15:55:12 -0800 Subject: drivers/rtc/Kconfig: disable RTC_DRV_CMOS on Atari On ARAnyM (emulating an Atari Falcon, which doesn't have an RTC IRQ, as the Second Multi Function Peripheral MFP 68901 is available on Atari TT only), rtc-cmos doesn't work well: - The date is of by 32 years (2045 instead of 2013): rtc_cmos rtc_cmos: setting system clock to 2045-12-02 10:56:17 UTC (2395824977) - The hwclock utility doesn't work: hwclock: ioctl() to /dev/rtc to turn on update interrupts failed unexpectedly, errno=5: Input/output error. As rtc-generic works fine for the RTC part, and nvram works for the NVRAM part, we'll continue on using that. Signed-off-by: Geert Uytterhoeven Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 4bd489c67e5e..609b069a278c 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -637,7 +637,7 @@ comment "Platform RTC drivers" config RTC_DRV_CMOS tristate "PC-style 'CMOS'" - depends on X86 || ARM || M32R || ATARI || PPC || MIPS || SPARC64 + depends on X86 || ARM || M32R || PPC || MIPS || SPARC64 default y if X86 help Say "yes" here to get direct support for the real time clock -- cgit v1.2.3 From 7ab26cd1ef817bca74cf82116eaf9eb5fe4a56c7 Mon Sep 17 00:00:00 2001 From: Duan Jiong Date: Thu, 23 Jan 2014 15:55:13 -0800 Subject: drivers/rtc/rtc-pcf2127.c: replace IS_ERR and PTR_ERR with PTR_ERR_OR_ZERO Fix a coccinelle error regarding usage of IS_ERR and PTR_ERR instead of PTR_ERR_OR_ZERO. Signed-off-by: Duan Jiong Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-pcf2127.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 1ee514a3972c..9bd842e97749 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -197,10 +197,7 @@ static int pcf2127_probe(struct i2c_client *client, pcf2127_driver.driver.name, &pcf2127_rtc_ops, THIS_MODULE); - if (IS_ERR(pcf2127->rtc)) - return PTR_ERR(pcf2127->rtc); - - return 0; + return PTR_ERR_OR_ZERO(pcf2127->rtc); } static const struct i2c_device_id pcf2127_id[] = { -- cgit v1.2.3 From 9d2b7e532da8aadfcc1bd85b62ec5dd853e870e3 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 23 Jan 2014 15:55:14 -0800 Subject: rtc: honor device tree /alias entries when assigning IDs Assign RTC device IDs based on device tree /aliases entries if present, falling back to the existing numbering scheme if there is no /aliases entry (which includes when the system isn't booted using DT), or there is a numbering conflict. This is useful in systems with multiple RTC devices, to ensure that the best RTC device is selected as /dev/rtc0, which provides the overall system time. For example, Tegra has an on-SoC RTC that is not battery backed, typically coupled with an off-SoC RTC that is battery backed. Only the latter is useful for populating the system time, yet the former is useful e.g. for wakeup timing, since the time is not lost when the system is sleeps. Signed-off-by: Stephen Warren Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/class.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 02426812bebc..589351ef75d0 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -14,6 +14,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include #include #include @@ -157,12 +158,27 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, { struct rtc_device *rtc; struct rtc_wkalrm alrm; - int id, err; + int of_id = -1, id = -1, err; + + if (dev->of_node) + of_id = of_alias_get_id(dev->of_node, "rtc"); + else if (dev->parent && dev->parent->of_node) + of_id = of_alias_get_id(dev->parent->of_node, "rtc"); + + if (of_id >= 0) { + id = ida_simple_get(&rtc_ida, of_id, of_id + 1, + GFP_KERNEL); + if (id < 0) + dev_warn(dev, "/aliases ID %d not available\n", + of_id); + } - id = ida_simple_get(&rtc_ida, 0, 0, GFP_KERNEL); if (id < 0) { - err = id; - goto exit; + id = ida_simple_get(&rtc_ida, 0, 0, GFP_KERNEL); + if (id < 0) { + err = id; + goto exit; + } } rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL); -- cgit v1.2.3 From 24b34472e2e6e3815f36e39d6996e3b39ebb2a5e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 23 Jan 2014 15:55:15 -0800 Subject: drivers/rtc/rtc-cmos.c: propagate hpet_register_irq_handler() failure If hpet_register_irq_handler() fails, cmos_do_probe() will incorrectly return 0. Reported-by: Julia Lawall Cc: John Stultz Cc: Grant Likely Cc: Rob Herring Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-cmos.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index f28b45856d66..cae212f30d65 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -756,11 +756,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) irq_handler_t rtc_cmos_int_handler; if (is_hpet_enabled()) { - int err; - rtc_cmos_int_handler = hpet_rtc_interrupt; - err = hpet_register_irq_handler(cmos_interrupt); - if (err != 0) { + retval = hpet_register_irq_handler(cmos_interrupt); + if (retval) { dev_warn(dev, "hpet_register_irq_handler " " failed in rtc_init()."); goto cleanup1; -- cgit v1.2.3 From 5516f0971793a0f7d0d54bf0220b6b2e13a05d7e Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 23 Jan 2014 15:55:16 -0800 Subject: drivers/rtc/rtc-ds1742.c: remove redundant of_match_ptr() helper 'ds1742_rtc_of_match' is always compiled in. Hence the helper macro is not needed. Signed-off-by: Sachin Kamat Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1742.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index d7f74f5e9090..5a1f3b2a8f1e 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -228,7 +228,7 @@ static struct platform_driver ds1742_rtc_driver = { .driver = { .name = "rtc-ds1742", .owner = THIS_MODULE, - .of_match_table = of_match_ptr(ds1742_rtc_of_match), + .of_match_table = ds1742_rtc_of_match, }, }; -- cgit v1.2.3 From 156e3526e8509140723c3af3b6b5468a854cc2fa Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 23 Jan 2014 15:55:17 -0800 Subject: drivers/rtc/rtc-hym8563.c: remove redundant of_match_ptr() helper 'hym8563_dt_idtable' is always compiled in. Hence the helper macro is not needed. Signed-off-by: Sachin Kamat Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-hym8563.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index b56e3d3fbfd3..6118000b787a 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c @@ -593,7 +593,7 @@ static struct i2c_driver hym8563_driver = { .name = "rtc-hym8563", .owner = THIS_MODULE, .pm = &hym8563_pm_ops, - .of_match_table = of_match_ptr(hym8563_dt_idtable), + .of_match_table = hym8563_dt_idtable, }, .probe = hym8563_probe, .id_table = hym8563_id, -- cgit v1.2.3 From 28ed893c02e7da25792e6742a78b679662a144e3 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 23 Jan 2014 15:55:18 -0800 Subject: drivers/rtc/rtc-hym8563.c: staticize local symbol 'hym8563_clkout_ops' is used only in this file. Signed-off-by: Sachin Kamat Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-hym8563.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index 6118000b787a..bd628a6f981d 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c @@ -389,7 +389,7 @@ static int hym8563_clkout_is_prepared(struct clk_hw *hw) return !(ret & HYM8563_CLKOUT_DISABLE); } -const struct clk_ops hym8563_clkout_ops = { +static const struct clk_ops hym8563_clkout_ops = { .prepare = hym8563_clkout_prepare, .unprepare = hym8563_clkout_unprepare, .is_prepared = hym8563_clkout_is_prepared, -- cgit v1.2.3 From 75ea799df4cb07e505c91b4abaa87bc28aad3e66 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 23 Jan 2014 15:55:19 -0800 Subject: rtc: max8907: weekday encoding fixes The current MAX8907 driver has two issues related to weekday value handling: 1) The HW WEEKDAY register has range 0..6 rather than 1..7 as documented. Note that I validated the actual HW range by observing the HW register roll from 6->0 rather than 6->7->1 as would otherwise be expected. This matches Linux's tm_wday range of 0..6. When the CMOS RAM content is lost, the date returned from the device is 2007-01-01 00:00:00, which is a Monday. The WEEKDAY register reads 1 in this case. This matches the numbering in Linux's tm_wday field. Hence we should write Linux's tm_wday value to the register without modifying it. Hence, remove the +1/-1 calculations for WEEKDAY/tm_wday. 2) There's no need to make alarms match on the WEEKDAY register, since the other fields together uniquely define the alarm date/time. Ignoring the WEEKDAY value in the match isolates the driver from any incorrect value in the current time copy of the WEEKDAY register. Each change individually, or both together, solves an issue that I observed; "hwclock -r" would time out waiting for its alarm to fire if the CMOS RAM content had been lost, and hence the WEEKDAY register value mismatched what the driver expected it to be. "hwclock -w" would solve this by over-writing the HW default WEEKDAY register value with what the driver expected. Signed-off-by: Stephen Warren Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-max8907.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-max8907.c b/drivers/rtc/rtc-max8907.c index 8e45b3c4aa2f..3032178bd9e6 100644 --- a/drivers/rtc/rtc-max8907.c +++ b/drivers/rtc/rtc-max8907.c @@ -51,7 +51,7 @@ static irqreturn_t max8907_irq_handler(int irq, void *data) { struct max8907_rtc *rtc = data; - regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x7f, 0); + regmap_write(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0); rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); @@ -64,7 +64,7 @@ static void regs_to_tm(u8 *regs, struct rtc_time *tm) bcd2bin(regs[RTC_YEAR1]) - 1900; tm->tm_mon = bcd2bin(regs[RTC_MONTH] & 0x1f) - 1; tm->tm_mday = bcd2bin(regs[RTC_DATE] & 0x3f); - tm->tm_wday = (regs[RTC_WEEKDAY] & 0x07) - 1; + tm->tm_wday = (regs[RTC_WEEKDAY] & 0x07); if (regs[RTC_HOUR] & HOUR_12) { tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x01f); if (tm->tm_hour == 12) @@ -88,7 +88,7 @@ static void tm_to_regs(struct rtc_time *tm, u8 *regs) regs[RTC_YEAR1] = bin2bcd(low); regs[RTC_MONTH] = bin2bcd(tm->tm_mon + 1); regs[RTC_DATE] = bin2bcd(tm->tm_mday); - regs[RTC_WEEKDAY] = tm->tm_wday + 1; + regs[RTC_WEEKDAY] = tm->tm_wday; regs[RTC_HOUR] = bin2bcd(tm->tm_hour); regs[RTC_MIN] = bin2bcd(tm->tm_min); regs[RTC_SEC] = bin2bcd(tm->tm_sec); @@ -153,7 +153,7 @@ static int max8907_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) tm_to_regs(&alrm->time, regs); /* Disable alarm while we update the target time */ - ret = regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x7f, 0); + ret = regmap_write(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0); if (ret < 0) return ret; @@ -163,8 +163,7 @@ static int max8907_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) return ret; if (alrm->enabled) - ret = regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL, - 0x7f, 0x7f); + ret = regmap_write(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x77); return ret; } -- cgit v1.2.3 From 11ba5a1eeb5406c58ffda0fc07360b2ef5c4f176 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 23 Jan 2014 15:55:19 -0800 Subject: drivers/rtc/rtc-s5m.c: s5m_rtc_{suspend,resume}() should depend on CONFIG_PM_SLEEP If CONFIG_PM_SLEEP=n: drivers/rtc/rtc-s5m.c:643: warning: `s5m_rtc_resume' defined but not used drivers/rtc/rtc-s5m.c:654: warning: `s5m_rtc_suspend' defined but not used Signed-off-by: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-s5m.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index ae8119dc2846..476af93543f6 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -639,6 +639,7 @@ static void s5m_rtc_shutdown(struct platform_device *pdev) s5m_rtc_enable_smpl(info, false); } +#ifdef CONFIG_PM_SLEEP static int s5m_rtc_resume(struct device *dev) { struct s5m_rtc_info *info = dev_get_drvdata(dev); @@ -660,6 +661,7 @@ static int s5m_rtc_suspend(struct device *dev) return ret; } +#endif /* CONFIG_PM_SLEEP */ static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume); -- cgit v1.2.3 From d643a49ae16c755b3dc2ef897438b7d9c6dd488b Mon Sep 17 00:00:00 2001 From: Andreas Werner Date: Thu, 23 Jan 2014 15:55:20 -0800 Subject: drivers/rtc/rtc-rx8581.c: add SMBus-only adapters support Add support for SMBus-only adapters (e.g. i2c-piix4). The driver has implemented only support for I2C adapters which implement the I2C_FUNC_SMBUS_I2C_BLOCK functionality before. With this patch it is possible to load and use the RTC driver with I2C and SMBUS adapters like the rtc-ds1307 does. Tested on AMD G Series Platform (i2c-piix4 adapter driver). Signed-off-by: Andreas Werner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-rx8581.c | 81 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c index 00b0eb7fe166..de8d9c427782 100644 --- a/drivers/rtc/rtc-rx8581.c +++ b/drivers/rtc/rtc-rx8581.c @@ -52,8 +52,45 @@ #define RX8581_CTRL_STOP 0x02 /* STOP bit */ #define RX8581_CTRL_RESET 0x01 /* RESET bit */ +struct rx8581 { + struct i2c_client *client; + struct rtc_device *rtc; + s32 (*read_block_data)(const struct i2c_client *client, u8 command, + u8 length, u8 *values); + s32 (*write_block_data)(const struct i2c_client *client, u8 command, + u8 length, const u8 *values); +}; + static struct i2c_driver rx8581_driver; +static int rx8581_read_block_data(const struct i2c_client *client, u8 command, + u8 length, u8 *values) +{ + s32 i, data; + + for (i = 0; i < length; i++) { + data = i2c_smbus_read_byte_data(client, command + i); + if (data < 0) + return data; + values[i] = data; + } + return i; +} + +static int rx8581_write_block_data(const struct i2c_client *client, u8 command, + u8 length, const u8 *values) +{ + s32 i, ret; + + for (i = 0; i < length; i++) { + ret = i2c_smbus_write_byte_data(client, command + i, + values[i]); + if (ret < 0) + return ret; + } + return length; +} + /* * In the routines that deal directly with the rx8581 hardware, we use * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. @@ -62,6 +99,7 @@ static int rx8581_get_datetime(struct i2c_client *client, struct rtc_time *tm) { unsigned char date[7]; int data, err; + struct rx8581 *rx8581 = i2c_get_clientdata(client); /* First we ensure that the "update flag" is not set, we read the * time and date then re-read the "update flag". If the update flag @@ -80,14 +118,13 @@ static int rx8581_get_datetime(struct i2c_client *client, struct rtc_time *tm) err = i2c_smbus_write_byte_data(client, RX8581_REG_FLAG, (data & ~RX8581_FLAG_UF)); if (err != 0) { - dev_err(&client->dev, "Unable to write device " - "flags\n"); + dev_err(&client->dev, "Unable to write device flags\n"); return -EIO; } } /* Now read time and date */ - err = i2c_smbus_read_i2c_block_data(client, RX8581_REG_SC, + err = rx8581->read_block_data(client, RX8581_REG_SC, 7, date); if (err < 0) { dev_err(&client->dev, "Unable to read date\n"); @@ -140,6 +177,7 @@ static int rx8581_set_datetime(struct i2c_client *client, struct rtc_time *tm) { int data, err; unsigned char buf[7]; + struct rx8581 *rx8581 = i2c_get_clientdata(client); dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, " "mday=%d, mon=%d, year=%d, wday=%d\n", @@ -176,7 +214,7 @@ static int rx8581_set_datetime(struct i2c_client *client, struct rtc_time *tm) } /* write register's data */ - err = i2c_smbus_write_i2c_block_data(client, RX8581_REG_SC, 7, buf); + err = rx8581->write_block_data(client, RX8581_REG_SC, 7, buf); if (err < 0) { dev_err(&client->dev, "Unable to write to date registers\n"); return -EIO; @@ -231,22 +269,39 @@ static const struct rtc_class_ops rx8581_rtc_ops = { static int rx8581_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct rtc_device *rtc; + struct rx8581 *rx8581; dev_dbg(&client->dev, "%s\n", __func__); - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) - return -ENODEV; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA) + && !i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) + return -EIO; - dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); + rx8581 = devm_kzalloc(&client->dev, sizeof(struct rx8581), GFP_KERNEL); + if (!rx8581) + return -ENOMEM; - rtc = devm_rtc_device_register(&client->dev, rx8581_driver.driver.name, - &rx8581_rtc_ops, THIS_MODULE); + i2c_set_clientdata(client, rx8581); + rx8581->client = client; - if (IS_ERR(rtc)) - return PTR_ERR(rtc); + if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { + rx8581->read_block_data = i2c_smbus_read_i2c_block_data; + rx8581->write_block_data = i2c_smbus_write_i2c_block_data; + } else { + rx8581->read_block_data = rx8581_read_block_data; + rx8581->write_block_data = rx8581_write_block_data; + } - i2c_set_clientdata(client, rtc); + dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); + + rx8581->rtc = devm_rtc_device_register(&client->dev, + rx8581_driver.driver.name, &rx8581_rtc_ops, THIS_MODULE); + + if (IS_ERR(rx8581->rtc)) { + dev_err(&client->dev, + "unable to register the class device\n"); + return PTR_ERR(rx8581->rtc); + } return 0; } -- cgit v1.2.3 From 63509beaf7ed7a9dc8c574be61189fce791489f0 Mon Sep 17 00:00:00 2001 From: Micky Ching Date: Thu, 23 Jan 2014 15:56:17 -0800 Subject: drivers/memstick/host/rtsx_pci_ms.c: fix ms card data transfer bug This patch is used to add support for ms card. The main difference between ms card and mspro card is long data transfer mode. mspro card can use auto mode DMA for long data transfer, but ms can not use this mode, it should use normal mode DMA. The memstick core added support for ms card, but the original driver will make ms card fail at initialization, because it uses auto mode DMA. This patch makes the ms card work properly. Signed-off-by: Micky Ching Cc: Maxim Levitsky Cc: Samuel Ortiz Cc: Alex Dubov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/memstick/host/rtsx_pci_ms.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/memstick/host/rtsx_pci_ms.c b/drivers/memstick/host/rtsx_pci_ms.c index 25f8f93decb6..2a635b6fdaf7 100644 --- a/drivers/memstick/host/rtsx_pci_ms.c +++ b/drivers/memstick/host/rtsx_pci_ms.c @@ -145,6 +145,8 @@ static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir, unsigned int length = sg->length; u16 sec_cnt = (u16)(length / 512); u8 val, trans_mode, dma_dir; + struct memstick_dev *card = host->msh->card; + bool pro_card = card->id.type == MEMSTICK_TYPE_PRO; dev_dbg(ms_dev(host), "%s: tpc = 0x%02x, data_dir = %s, length = %d\n", __func__, tpc, (data_dir == READ) ? "READ" : "WRITE", @@ -152,19 +154,21 @@ static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir, if (data_dir == READ) { dma_dir = DMA_DIR_FROM_CARD; - trans_mode = MS_TM_AUTO_READ; + trans_mode = pro_card ? MS_TM_AUTO_READ : MS_TM_NORMAL_READ; } else { dma_dir = DMA_DIR_TO_CARD; - trans_mode = MS_TM_AUTO_WRITE; + trans_mode = pro_card ? MS_TM_AUTO_WRITE : MS_TM_NORMAL_WRITE; } rtsx_pci_init_cmd(pcr); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_H, - 0xFF, (u8)(sec_cnt >> 8)); - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_L, - 0xFF, (u8)sec_cnt); + if (pro_card) { + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_H, + 0xFF, (u8)(sec_cnt >> 8)); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_L, + 0xFF, (u8)sec_cnt); + } rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0, @@ -192,8 +196,14 @@ static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir, } rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val); - if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT)) - return -EIO; + if (pro_card) { + if (val & (MS_INT_CMDNK | MS_INT_ERR | + MS_CRC16_ERR | MS_RDY_TIMEOUT)) + return -EIO; + } else { + if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) + return -EIO; + } return 0; } @@ -462,8 +472,8 @@ static int rtsx_pci_ms_set_param(struct memstick_host *msh, clock = 19000000; ssc_depth = RTSX_SSC_DEPTH_500K; - err = rtsx_pci_write_register(pcr, MS_CFG, - 0x18, MS_BUS_WIDTH_1); + err = rtsx_pci_write_register(pcr, MS_CFG, 0x58, + MS_BUS_WIDTH_1 | PUSH_TIME_DEFAULT); if (err < 0) return err; } else if (value == MEMSTICK_PAR4) { -- cgit v1.2.3 From 3089a4c8d3abc7e2ab105d1d39d415110d1566d6 Mon Sep 17 00:00:00 2001 From: Evgeny Boger Date: Thu, 23 Jan 2014 15:56:18 -0800 Subject: drivers/w1/masters/w1-gpio.c: add strong pullup emulation Strong pullup is emulated by driving pin logic high after write command when using tri-state push-pull GPIO. Signed-off-by: Evgeny Boger Cc: Greg KH Acked-by: David Fries Acked-by: Evgeniy Polyakov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/w1/masters/w1-gpio.c | 22 ++++++++++++++++++++++ drivers/w1/w1_int.c | 12 ------------ include/linux/w1-gpio.h | 1 + 3 files changed, 23 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c index e36b18b2817b..9709b8b484ba 100644 --- a/drivers/w1/masters/w1-gpio.c +++ b/drivers/w1/masters/w1-gpio.c @@ -18,10 +18,31 @@ #include #include #include +#include #include "../w1.h" #include "../w1_int.h" +static u8 w1_gpio_set_pullup(void *data, int delay) +{ + struct w1_gpio_platform_data *pdata = data; + + if (delay) { + pdata->pullup_duration = delay; + } else { + if (pdata->pullup_duration) { + gpio_direction_output(pdata->pin, 1); + + msleep(pdata->pullup_duration); + + gpio_direction_input(pdata->pin); + } + pdata->pullup_duration = 0; + } + + return 0; +} + static void w1_gpio_write_bit_dir(void *data, u8 bit) { struct w1_gpio_platform_data *pdata = data; @@ -132,6 +153,7 @@ static int w1_gpio_probe(struct platform_device *pdev) } else { gpio_direction_input(pdata->pin); master->write_bit = w1_gpio_write_bit_dir; + master->set_pullup = w1_gpio_set_pullup; } err = w1_add_master_device(master); diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index 5a98649f6abc..590bd8a7cd1b 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c @@ -117,18 +117,6 @@ int w1_add_master_device(struct w1_bus_master *master) printk(KERN_ERR "w1_add_master_device: invalid function set\n"); return(-EINVAL); } - /* While it would be electrically possible to make a device that - * generated a strong pullup in bit bang mode, only hardware that - * controls 1-wire time frames are even expected to support a strong - * pullup. w1_io.c would need to support calling set_pullup before - * the last write_bit operation of a w1_write_8 which it currently - * doesn't. - */ - if (!master->write_byte && !master->touch_bit && master->set_pullup) { - printk(KERN_ERR "w1_add_master_device: set_pullup requires " - "write_byte or touch_bit, disabling\n"); - master->set_pullup = NULL; - } /* Lock until the device is added (or not) to w1_masters. */ mutex_lock(&w1_mlock); diff --git a/include/linux/w1-gpio.h b/include/linux/w1-gpio.h index 065e3ae79ab0..d58594a32324 100644 --- a/include/linux/w1-gpio.h +++ b/include/linux/w1-gpio.h @@ -20,6 +20,7 @@ struct w1_gpio_platform_data { unsigned int is_open_drain:1; void (*enable_external_pullup)(int enable); unsigned int ext_pullup_enable_pin; + unsigned int pullup_duration; }; #endif /* _LINUX_W1_GPIO_H */ -- cgit v1.2.3