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 <philipp.zabel@gmail.com>
Signed-off-by: Samuel Ortiz <sameo@openedhand.com>
#include <linux/irq.h>
#include <linux/pm.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/pm.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/mfd/core.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/mfd/core.h>
struct mfd_cell *cell;
int irq;
int active_high;
struct mfd_cell *cell;
int irq;
int active_high;
int slave_present;
void *reset_complete;
void *read_complete;
int slave_present;
void *reset_complete;
void *read_complete;
static void ds1wm_up(struct ds1wm_data *ds1wm_data)
{
static void ds1wm_up(struct ds1wm_data *ds1wm_data)
{
+ int divisor;
+ struct ds1wm_driver_data *plat = ds1wm_data->cell->driver_data;
if (ds1wm_data->cell->enable)
ds1wm_data->cell->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);
- divisor = ds1wm_find_divisor(gclk);
+ divisor = ds1wm_find_divisor(plat->clock_rate);
if (divisor == 0) {
dev_err(&ds1wm_data->pdev->dev,
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);
return;
}
ds1wm_write_register(ds1wm_data, DS1WM_CLKDIV, divisor);
if (ds1wm_data->cell->disable)
ds1wm_data->cell->disable(ds1wm_data->pdev);
if (ds1wm_data->cell->disable)
ds1wm_data->cell->disable(ds1wm_data->pdev);
-
- clk_disable(ds1wm_data->clk);
}
/* --------------------------------------------------------------------- */
}
/* --------------------------------------------------------------------- */
- 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)
ds1wm_up(ds1wm_data);
ds1wm_master.data = (void *)ds1wm_data;
ret = w1_add_master_device(&ds1wm_master);
if (ret)
-err3:
- ds1wm_down(ds1wm_data);
- clk_put(ds1wm_data->clk);
+ ds1wm_down(ds1wm_data);
free_irq(ds1wm_data->irq, ds1wm_data);
err1:
iounmap(ds1wm_data->map);
free_irq(ds1wm_data->irq, ds1wm_data);
err1:
iounmap(ds1wm_data->map);
w1_remove_master_device(&ds1wm_master);
ds1wm_down(ds1wm_data);
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);
free_irq(ds1wm_data->irq, ds1wm_data);
iounmap(ds1wm_data->map);
kfree(ds1wm_data);
struct ds1wm_driver_data {
int active_high;
struct ds1wm_driver_data {
int active_high;