From 22e2df7d5ff50e5a62d4945b13c83525a2617ef5 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Wed, 4 Feb 2009 22:43:28 +0100 Subject: mfd: remove duplicated #include from pcf50633 Removed duplicated #include in drivers/mfd/pcf50633-core.c Signed-off-by: Huang Weiyi Signed-off-by: Samuel Ortiz --- drivers/mfd/pcf50633-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 2e36057..7793932 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include -- cgit v1.1 From 9dfd338198bec67ebc82ed363078f9d8aa74ec3e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 4 Feb 2009 22:43:55 +0100 Subject: mfd: Use bulk read to fill WM8350 register cache Some I2C controllers have high overheads for setting up I2C operations which makes the register cache setup on startup excessively slow since it does a lot of small transactions. Reduce this overhead by doing a bulk read of the entire register bank and filtering out what we don't need later. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm8350-core.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index b457a05..f22b18b 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c @@ -1238,7 +1238,7 @@ static int wm8350_create_cache(struct wm8350 *wm8350, int type, int mode) } wm8350->reg_cache = - kzalloc(sizeof(u16) * (WM8350_MAX_REGISTER + 1), GFP_KERNEL); + kmalloc(sizeof(u16) * (WM8350_MAX_REGISTER + 1), GFP_KERNEL); if (wm8350->reg_cache == NULL) return -ENOMEM; @@ -1246,17 +1246,20 @@ static int wm8350_create_cache(struct wm8350 *wm8350, int type, int mode) * a PMIC so the device many not be in a virgin state and we * can't rely on the silicon values. */ + ret = wm8350->read_dev(wm8350, 0, + sizeof(u16) * (WM8350_MAX_REGISTER + 1), + wm8350->reg_cache); + if (ret < 0) { + dev_err(wm8350->dev, + "failed to read initial cache values\n"); + goto out; + } + + /* Mask out uncacheable/unreadable bits and the audio. */ for (i = 0; i < WM8350_MAX_REGISTER; i++) { - /* audio register range */ if (wm8350_reg_io_map[i].readable && (i < WM8350_CLOCK_CONTROL_1 || i > WM8350_AIF_TEST)) { - ret = wm8350->read_dev(wm8350, i, 2, (char *)&value); - if (ret < 0) { - dev_err(wm8350->dev, - "failed to read initial cache value\n"); - goto out; - } - value = be16_to_cpu(value); + value = be16_to_cpu(wm8350->reg_cache[i]); value &= wm8350_reg_io_map[i].readable; value &= ~wm8350_reg_io_map[i].vol; wm8350->reg_cache[i] = value; -- cgit v1.1 From 3206450355100eae8e033645318b95bb60f1faff Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 6 Feb 2009 15:27:13 +0100 Subject: mfd: Support active high IRQs on WM835x Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm8350-core.c | 16 +++++++++++++++- include/linux/mfd/wm8350/core.h | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index f22b18b..a285cc0 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c @@ -1438,7 +1438,21 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq, mutex_init(&wm8350->irq_mutex); INIT_WORK(&wm8350->irq_work, wm8350_irq_worker); if (irq) { - ret = request_irq(irq, wm8350_irq, 0, + int flags = 0; + + if (pdata && pdata->irq_high) { + flags |= IRQF_TRIGGER_HIGH; + + wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1, + WM8350_IRQ_POL); + } else { + flags |= IRQF_TRIGGER_LOW; + + wm8350_clear_bits(wm8350, WM8350_SYSTEM_CONTROL_1, + WM8350_IRQ_POL); + } + + ret = request_irq(irq, wm8350_irq, flags, "wm8350", wm8350); if (ret != 0) { dev_err(wm8350->dev, "Failed to request IRQ: %d\n", diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h index 980669d..42cca67 100644 --- a/include/linux/mfd/wm8350/core.h +++ b/include/linux/mfd/wm8350/core.h @@ -640,9 +640,11 @@ struct wm8350 { * * @init: Function called during driver initialisation. Should be * used by the platform to configure GPIO functions and similar. + * @irq_high: Set if WM8350 IRQ is active high. */ struct wm8350_platform_data { int (*init)(struct wm8350 *wm8350); + int irq_high; }; -- cgit v1.1 From a23a175795cdb202619ac176129b2f0c2a5c9456 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 17 Feb 2009 10:06:41 +0100 Subject: mfd: convert DS1WM to use MFD core This patch converts the DS1WM driver into an MFD cell. It also calculates the bus_shift parameter from the memory resource size. Signed-off-by: Philipp Zabel Signed-off-by: Samuel Ortiz --- drivers/w1/masters/ds1wm.c | 31 ++++++++++++++++++++----------- include/linux/ds1wm.h | 12 ------------ include/linux/mfd/ds1wm.h | 5 +++++ 3 files changed, 25 insertions(+), 23 deletions(-) delete mode 100644 include/linux/ds1wm.h create mode 100644 include/linux/mfd/ds1wm.h diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c index 29e144f..f1e6b3d 100644 --- a/drivers/w1/masters/ds1wm.c +++ b/drivers/w1/masters/ds1wm.c @@ -19,7 +19,8 @@ #include #include #include -#include +#include +#include #include @@ -89,7 +90,7 @@ struct ds1wm_data { void __iomem *map; int bus_shift; /* # of shifts to calc register offsets */ struct platform_device *pdev; - struct ds1wm_platform_data *pdata; + struct mfd_cell *cell; int irq; int active_high; struct clk *clk; @@ -217,8 +218,8 @@ static void ds1wm_up(struct ds1wm_data *ds1wm_data) { int gclk, divisor; - if (ds1wm_data->pdata->enable) - ds1wm_data->pdata->enable(ds1wm_data->pdev); + if (ds1wm_data->cell->enable) + ds1wm_data->cell->enable(ds1wm_data->pdev); gclk = clk_get_rate(ds1wm_data->clk); clk_enable(ds1wm_data->clk); @@ -244,8 +245,8 @@ static void ds1wm_down(struct ds1wm_data *ds1wm_data) ds1wm_write_register(ds1wm_data, DS1WM_INT_EN, ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0); - if (ds1wm_data->pdata->disable) - ds1wm_data->pdata->disable(ds1wm_data->pdev); + if (ds1wm_data->cell->disable) + ds1wm_data->cell->disable(ds1wm_data->pdev); clk_disable(ds1wm_data->clk); } @@ -330,13 +331,18 @@ static struct w1_bus_master ds1wm_master = { static int ds1wm_probe(struct platform_device *pdev) { struct ds1wm_data *ds1wm_data; - struct ds1wm_platform_data *plat; + struct ds1wm_driver_data *plat; struct resource *res; + struct mfd_cell *cell; int ret; if (!pdev) return -ENODEV; + cell = pdev->dev.platform_data; + if (!cell) + return -ENODEV; + ds1wm_data = kzalloc(sizeof(*ds1wm_data), GFP_KERNEL); if (!ds1wm_data) return -ENOMEM; @@ -348,15 +354,18 @@ static int ds1wm_probe(struct platform_device *pdev) ret = -ENXIO; goto err0; } - ds1wm_data->map = ioremap(res->start, res->end - res->start + 1); + ds1wm_data->map = ioremap(res->start, resource_size(res)); if (!ds1wm_data->map) { ret = -ENOMEM; goto err0; } - plat = pdev->dev.platform_data; - ds1wm_data->bus_shift = plat->bus_shift; + plat = cell->driver_data; + + /* calculate bus shift from mem resource */ + ds1wm_data->bus_shift = resource_size(res) >> 3; + ds1wm_data->pdev = pdev; - ds1wm_data->pdata = plat; + ds1wm_data->cell = cell; res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { diff --git a/include/linux/ds1wm.h b/include/linux/ds1wm.h deleted file mode 100644 index d3c65e4..0000000 --- a/include/linux/ds1wm.h +++ /dev/null @@ -1,12 +0,0 @@ -/* platform data for the DS1WM driver */ - -struct ds1wm_platform_data { - int bus_shift; /* number of shifts needed to calculate the - * offset between DS1WM registers; - * e.g. on h5xxx and h2200 this is 2 - * (registers aligned to 4-byte boundaries), - * while on hx4700 this is 1 */ - int active_high; - void (*enable)(struct platform_device *pdev); - void (*disable)(struct platform_device *pdev); -}; diff --git a/include/linux/mfd/ds1wm.h b/include/linux/mfd/ds1wm.h new file mode 100644 index 0000000..d4898ba --- /dev/null +++ b/include/linux/mfd/ds1wm.h @@ -0,0 +1,5 @@ +/* MFD cell driver data for the DS1WM driver */ + +struct ds1wm_driver_data { + int active_high; +}; -- cgit v1.1 From 0254a8f496f9c939d4068613ace4ffd0d9e6ece2 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 17 Feb 2009 10:06:45 +0100 Subject: mfd: convert PASIC3 to use MFD core This patch makes htc-pasic3 register the DS1WM and LED cell drivers through the MFD core infrastructure instead of allocating the platform devices manually. It also calculates the bus_shift parameter from the memory resource size. Signed-off-by: Philipp Zabel Signed-off-by: Samuel Ortiz --- drivers/mfd/Kconfig | 1 + drivers/mfd/htc-pasic3.c | 159 ++++++++++++++++++----------------------------- 2 files changed, 62 insertions(+), 98 deletions(-) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 75f35db..ee3927a 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -52,6 +52,7 @@ config HTC_EGPIO config HTC_PASIC3 tristate "HTC PASIC3 LED/DS1WM chip support" + select MFD_CORE help This core driver provides register access for the LED/DS1WM chips labeled "AIC2" and "AIC3", found on HTC Blueangel and diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c index 91b294d..92b6837 100644 --- a/drivers/mfd/htc-pasic3.c +++ b/drivers/mfd/htc-pasic3.c @@ -12,18 +12,17 @@ #include #include -#include #include #include #include #include +#include +#include #include struct pasic3_data { void __iomem *mapping; unsigned int bus_shift; - struct platform_device *ds1wm_pdev; - struct platform_device *led_pdev; }; #define REG_ADDR 5 @@ -65,46 +64,15 @@ EXPORT_SYMBOL(pasic3_read_register); /* for leds-pasic3 */ * LEDs */ -static int led_device_add(struct device *pasic3_dev, - const struct pasic3_leds_machinfo *pdata) -{ - struct pasic3_data *asic = pasic3_dev->driver_data; - struct platform_device *pdev; - int ret; - - pdev = platform_device_alloc("pasic3-led", -1); - if (!pdev) { - dev_dbg(pasic3_dev, "failed to allocate LED platform device\n"); - return -ENOMEM; - } - - ret = platform_device_add_data(pdev, pdata, - sizeof(struct pasic3_leds_machinfo)); - if (ret < 0) { - dev_dbg(pasic3_dev, "failed to add LED platform data\n"); - goto exit_pdev_put; - } - - pdev->dev.parent = pasic3_dev; - ret = platform_device_add(pdev); - if (ret < 0) { - dev_dbg(pasic3_dev, "failed to add LED platform device\n"); - goto exit_pdev_put; - } - - asic->led_pdev = pdev; - return 0; - -exit_pdev_put: - platform_device_put(pdev); - return ret; -} +static struct mfd_cell led_cell __initdata = { + .name = "leds-pasic3", +}; /* * DS1WM */ -static void ds1wm_enable(struct platform_device *pdev) +static int ds1wm_enable(struct platform_device *pdev) { struct device *dev = pdev->dev.parent; int c; @@ -113,9 +81,10 @@ static void ds1wm_enable(struct platform_device *pdev) pasic3_write_register(dev, 0x28, c & 0x7f); dev_dbg(dev, "DS1WM OWM_EN low (active) %02x\n", c & 0x7f); + return 0; } -static void ds1wm_disable(struct platform_device *pdev) +static int ds1wm_disable(struct platform_device *pdev) { struct device *dev = pdev->dev.parent; int c; @@ -124,56 +93,33 @@ static void ds1wm_disable(struct platform_device *pdev) pasic3_write_register(dev, 0x28, c | 0x80); dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02x\n", c | 0x80); + return 0; } -static struct ds1wm_platform_data ds1wm_pdata = { - .bus_shift = 2, - .enable = ds1wm_enable, - .disable = ds1wm_disable, +static struct ds1wm_driver_data ds1wm_pdata = { + .active_high = 0, }; -static int ds1wm_device_add(struct platform_device *pasic3_pdev, int bus_shift) -{ - struct device *pasic3_dev = &pasic3_pdev->dev; - struct pasic3_data *asic = pasic3_dev->driver_data; - struct platform_device *pdev; - int ret; - - pdev = platform_device_alloc("ds1wm", -1); - if (!pdev) { - dev_dbg(pasic3_dev, "failed to allocate DS1WM platform device\n"); - return -ENOMEM; - } - - ret = platform_device_add_resources(pdev, pasic3_pdev->resource, - pasic3_pdev->num_resources); - if (ret < 0) { - dev_dbg(pasic3_dev, "failed to add DS1WM resources\n"); - goto exit_pdev_put; - } - - ds1wm_pdata.bus_shift = asic->bus_shift; - ret = platform_device_add_data(pdev, &ds1wm_pdata, - sizeof(struct ds1wm_platform_data)); - if (ret < 0) { - dev_dbg(pasic3_dev, "failed to add DS1WM platform data\n"); - goto exit_pdev_put; - } - - pdev->dev.parent = pasic3_dev; - ret = platform_device_add(pdev); - if (ret < 0) { - dev_dbg(pasic3_dev, "failed to add DS1WM platform device\n"); - goto exit_pdev_put; - } - - asic->ds1wm_pdev = pdev; - return 0; +static struct resource ds1wm_resources[] __initdata = { + [0] = { + .start = 0, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 0, + .end = 0, + .flags = IORESOURCE_IRQ, + }, +}; -exit_pdev_put: - platform_device_put(pdev); - return ret; -} +static struct mfd_cell ds1wm_cell __initdata = { + .name = "ds1wm", + .enable = ds1wm_enable, + .disable = ds1wm_disable, + .driver_data = &ds1wm_pdata, + .num_resources = 2, + .resources = ds1wm_resources, +}; static int __init pasic3_probe(struct platform_device *pdev) { @@ -182,12 +128,27 @@ static int __init pasic3_probe(struct platform_device *pdev) struct pasic3_data *asic; struct resource *r; int ret; + int irq = 0; + + r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (r) { + ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags & + (IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE)); + irq = r->start; + } + + r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (r) { + ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags & + (IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE)); + irq = r->start; + } r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) return -ENXIO; - if (!request_mem_region(r->start, r->end - r->start + 1, "pasic3")) + if (!request_mem_region(r->start, resource_size(r), "pasic3")) return -EBUSY; asic = kzalloc(sizeof(struct pasic3_data), GFP_KERNEL); @@ -196,24 +157,29 @@ static int __init pasic3_probe(struct platform_device *pdev) platform_set_drvdata(pdev, asic); - if (pdata && pdata->bus_shift) - asic->bus_shift = pdata->bus_shift; - else - asic->bus_shift = 2; - - asic->mapping = ioremap(r->start, r->end - r->start + 1); + asic->mapping = ioremap(r->start, resource_size(r)); if (!asic->mapping) { dev_err(dev, "couldn't ioremap PASIC3\n"); kfree(asic); return -ENOMEM; } - ret = ds1wm_device_add(pdev, asic->bus_shift); + /* calculate bus shift from mem resource */ + asic->bus_shift = (resource_size(r) - 5) >> 3; + + /* the first 5 PASIC3 registers control the DS1WM */ + ds1wm_resources[0].end = (5 << asic->bus_shift) - 1; + ds1wm_cell.platform_data = &ds1wm_cell; + ds1wm_cell.data_size = sizeof(ds1wm_cell); + ret = mfd_add_devices(&pdev->dev, pdev->id, &ds1wm_cell, 1, r, irq); if (ret < 0) dev_warn(dev, "failed to register DS1WM\n"); if (pdata->led_pdata) { - ret = led_device_add(dev, pdata->led_pdata); + led_cell.driver_data = pdata->led_pdata; + led_cell.platform_data = &led_cell; + led_cell.data_size = sizeof(ds1wm_cell); + ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0); if (ret < 0) dev_warn(dev, "failed to register LED device\n"); } @@ -226,14 +192,11 @@ static int pasic3_remove(struct platform_device *pdev) struct pasic3_data *asic = platform_get_drvdata(pdev); struct resource *r; - if (asic->led_pdev) - platform_device_unregister(asic->led_pdev); - if (asic->ds1wm_pdev) - platform_device_unregister(asic->ds1wm_pdev); + mfd_remove_devices(&pdev->dev); iounmap(asic->mapping); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(r->start, r->end - r->start + 1); + release_mem_region(r->start, resource_size(r)); kfree(asic); return 0; } -- cgit v1.1 From 0ef2067d0fdb0572bd0df288d1d32e27c929d824 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 17 Feb 2009 10:06:48 +0100 Subject: pxa/magician: remove deprecated .bus_shift from PASIC3 platform_data The PASIC3 driver now calculates its register spacing from the resource size. Signed-off-by: Philipp Zabel Signed-off-by: Samuel Ortiz --- arch/arm/mach-pxa/magician.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index d46b367..deeea1c 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -507,7 +507,6 @@ static struct resource pasic3_resources[] = { }; static struct pasic3_platform_data pasic3_platform_data = { - .bus_shift = 2, .led_pdata = &pasic3_leds_info, .clock_rate = 4000000, }; -- cgit v1.1 From b72019dbd126e60bb5f9f350f76127b1527facba Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 17 Feb 2009 10:06:52 +0100 Subject: mfd: remove unused PASIC3 bus_shift field Removes the now-unused bus_shift field from pasic3_platform_data. Signed-off-by: Philipp Zabel Signed-off-by: Samuel Ortiz --- include/linux/mfd/htc-pasic3.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/mfd/htc-pasic3.h b/include/linux/mfd/htc-pasic3.h index b4294f1..3d3ed67 100644 --- a/include/linux/mfd/htc-pasic3.h +++ b/include/linux/mfd/htc-pasic3.h @@ -48,7 +48,6 @@ struct pasic3_leds_machinfo { struct pasic3_platform_data { struct pasic3_leds_machinfo *led_pdata; - unsigned int bus_shift; unsigned int clock_rate; }; -- cgit v1.1 From 7d33ccbeecd8393cc690cf9a71008236cdd7cc2c Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 17 Feb 2009 10:09:19 +0100 Subject: mfd: remove DS1WM clock handling This driver requests a clock that usually is supplied by the MFD in which the DS1WM is contained. Currently, it is impossible for a MFD to register their clocks with the generic clock API due to different implementations across architectures. For now, this patch removes the clock handling from DS1WM altogether, trusting that the MFD enable/disable functions will switch the clock if needed. The clock rate is obtained from a new parameter in driver_data. Signed-off-by: Philipp Zabel Signed-off-by: Samuel Ortiz --- drivers/w1/masters/ds1wm.c | 27 +++++++-------------------- include/linux/mfd/ds1wm.h | 1 + 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c index f1e6b3d..37f08c8 100644 --- a/drivers/w1/masters/ds1wm.c +++ b/drivers/w1/masters/ds1wm.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -93,7 +92,6 @@ struct ds1wm_data { struct mfd_cell *cell; int irq; int active_high; - struct clk *clk; int slave_present; void *reset_complete; void *read_complete; @@ -216,17 +214,17 @@ static int ds1wm_find_divisor(int gclk) static void ds1wm_up(struct ds1wm_data *ds1wm_data) { - int gclk, divisor; + int divisor; + struct ds1wm_driver_data *plat = ds1wm_data->cell->driver_data; if (ds1wm_data->cell->enable) ds1wm_data->cell->enable(ds1wm_data->pdev); - gclk = clk_get_rate(ds1wm_data->clk); - clk_enable(ds1wm_data->clk); - divisor = ds1wm_find_divisor(gclk); + divisor = ds1wm_find_divisor(plat->clock_rate); if (divisor == 0) { dev_err(&ds1wm_data->pdev->dev, - "no suitable divisor for %dHz clock\n", gclk); + "no suitable divisor for %dHz clock\n", + plat->clock_rate); return; } ds1wm_write_register(ds1wm_data, DS1WM_CLKDIV, divisor); @@ -247,8 +245,6 @@ static void ds1wm_down(struct ds1wm_data *ds1wm_data) if (ds1wm_data->cell->disable) ds1wm_data->cell->disable(ds1wm_data->pdev); - - clk_disable(ds1wm_data->clk); } /* --------------------------------------------------------------------- */ @@ -385,26 +381,18 @@ static int ds1wm_probe(struct platform_device *pdev) if (ret) goto err1; - ds1wm_data->clk = clk_get(&pdev->dev, "ds1wm"); - if (IS_ERR(ds1wm_data->clk)) { - ret = PTR_ERR(ds1wm_data->clk); - goto err2; - } - ds1wm_up(ds1wm_data); ds1wm_master.data = (void *)ds1wm_data; ret = w1_add_master_device(&ds1wm_master); if (ret) - goto err3; + goto err2; return 0; -err3: - ds1wm_down(ds1wm_data); - clk_put(ds1wm_data->clk); err2: + ds1wm_down(ds1wm_data); free_irq(ds1wm_data->irq, ds1wm_data); err1: iounmap(ds1wm_data->map); @@ -443,7 +431,6 @@ static int ds1wm_remove(struct platform_device *pdev) w1_remove_master_device(&ds1wm_master); ds1wm_down(ds1wm_data); - clk_put(ds1wm_data->clk); free_irq(ds1wm_data->irq, ds1wm_data); iounmap(ds1wm_data->map); kfree(ds1wm_data); diff --git a/include/linux/mfd/ds1wm.h b/include/linux/mfd/ds1wm.h index d4898ba..be469a3 100644 --- a/include/linux/mfd/ds1wm.h +++ b/include/linux/mfd/ds1wm.h @@ -2,4 +2,5 @@ struct ds1wm_driver_data { int active_high; + int clock_rate; }; -- cgit v1.1 From 47c10edd715d420cabd8622a4a458e9ac755b24d Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 17 Feb 2009 10:09:44 +0100 Subject: mfd: PASIC3: supply clock_rate to DS1WM via driver_data Signed-off-by: Philipp Zabel Signed-off-by: Samuel Ortiz --- drivers/mfd/htc-pasic3.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c index 92b6837..386da15 100644 --- a/drivers/mfd/htc-pasic3.c +++ b/drivers/mfd/htc-pasic3.c @@ -167,15 +167,19 @@ static int __init pasic3_probe(struct platform_device *pdev) /* calculate bus shift from mem resource */ asic->bus_shift = (resource_size(r) - 5) >> 3; - /* the first 5 PASIC3 registers control the DS1WM */ - ds1wm_resources[0].end = (5 << asic->bus_shift) - 1; - ds1wm_cell.platform_data = &ds1wm_cell; - ds1wm_cell.data_size = sizeof(ds1wm_cell); - ret = mfd_add_devices(&pdev->dev, pdev->id, &ds1wm_cell, 1, r, irq); - if (ret < 0) - dev_warn(dev, "failed to register DS1WM\n"); - - if (pdata->led_pdata) { + if (pdata && pdata->clock_rate) { + ds1wm_pdata.clock_rate = pdata->clock_rate; + /* the first 5 PASIC3 registers control the DS1WM */ + ds1wm_resources[0].end = (5 << asic->bus_shift) - 1; + ds1wm_cell.platform_data = &ds1wm_cell; + ds1wm_cell.data_size = sizeof(ds1wm_cell); + ret = mfd_add_devices(&pdev->dev, pdev->id, + &ds1wm_cell, 1, r, irq); + if (ret < 0) + dev_warn(dev, "failed to register DS1WM\n"); + } + + if (pdata && pdata->led_pdata) { led_cell.driver_data = pdata->led_pdata; led_cell.platform_data = &led_cell; led_cell.data_size = sizeof(ds1wm_cell); -- cgit v1.1 From 3446d4bb93b4d8c7c5b667dd0271669f012fb166 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 17 Feb 2009 10:11:42 +0100 Subject: mfd: Storage class should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser Signed-off-by: Samuel Ortiz --- drivers/mfd/t7l66xb.c | 4 ++-- drivers/mfd/tc6393xb.c | 2 +- drivers/mfd/twl4030-irq.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 9f7024c..e9f4323 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c @@ -108,7 +108,7 @@ static int t7l66xb_mmc_disable(struct platform_device *mmc) /*--------------------------------------------------------------------------*/ -const static struct resource t7l66xb_mmc_resources[] = { +static const struct resource t7l66xb_mmc_resources[] = { { .start = 0x800, .end = 0x9ff, @@ -126,7 +126,7 @@ const static struct resource t7l66xb_mmc_resources[] = { }, }; -const static struct resource t7l66xb_nand_resources[] = { +static const struct resource t7l66xb_nand_resources[] = { { .start = 0xc00, .end = 0xc07, diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index f856e94..77a12fc 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c @@ -172,7 +172,7 @@ static struct resource __devinitdata tc6393xb_mmc_resources[] = { }, }; -const static struct resource tc6393xb_ohci_resources[] = { +static const struct resource tc6393xb_ohci_resources[] = { { .start = 0x3000, .end = 0x31ff, diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index b108760..aca2670 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c @@ -182,7 +182,7 @@ static int twl4030_irq_thread(void *data) long irq = (long)data; struct irq_desc *desc = irq_to_desc(irq); static unsigned i2c_errors; - const static unsigned max_i2c_errors = 100; + static const unsigned max_i2c_errors = 100; if (!desc) { pr_err("twl4030: Invalid IRQ: %ld\n", irq); -- cgit v1.1 From f3df0b7533ccad7bb3ef25383fea9c990b0033a2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 1 Mar 2009 20:11:58 +0100 Subject: mfd: Use the value of the final spin when reading the AUXADC Reverse the order of the tests for loop exit so we use a valid value before we time out. Vanishingly unlikely to happen since we retry for several times the expected conversion time. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm8350-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index a285cc0..c2be308 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c @@ -1111,7 +1111,7 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref) do { schedule_timeout_interruptible(1); reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1); - } while (--tries && (reg & WM8350_AUXADC_POLL)); + } while ((reg & WM8350_AUXADC_POLL) && --tries); if (!tries) dev_err(wm8350->dev, "adc chn %d read timeout\n", channel); -- cgit v1.1 From 895d9f0f15ff6b2d20bfbdc2b8205d1791437294 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 23 Mar 2009 00:46:18 +0100 Subject: mfd: fix MAINTAINERS entry The MFD git repo is living on kernel.org, and patches should be sent at sameo@linux.intel.com. Signed-off-by: Samuel Ortiz --- MAINTAINERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 6360b9b..587bc8b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3034,8 +3034,9 @@ S: Maintained MULTIFUNCTION DEVICES (MFD) P: Samuel Ortiz -M: sameo@openedhand.com +M: sameo@linux.intel.com L: linux-kernel@vger.kernel.org +T: git kernel.org:/pub/scm/linux/kernel/git/sameo/mfd-2.6.git S: Supported MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM -- cgit v1.1 From fa15ce8ad59e9653d50b8596596cb02d3566d4aa Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Tue, 31 Mar 2009 12:27:21 +0200 Subject: mfd: fix da903x warning The da903x interrupt handler is retruning an int instead of an irqreturn_t. Signed-off-by: Samuel Ortiz --- drivers/mfd/da903x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c index 99f8dcf..7283d88 100644 --- a/drivers/mfd/da903x.c +++ b/drivers/mfd/da903x.c @@ -413,7 +413,7 @@ static void da903x_irq_work(struct work_struct *work) enable_irq(chip->client->irq); } -static int da903x_irq_handler(int irq, void *data) +static irqreturn_t da903x_irq_handler(int irq, void *data) { struct da903x_chip *chip = data; -- cgit v1.1