in masters/ds1wm.c [506:612]
static int ds1wm_probe(struct platform_device *pdev)
{
struct ds1wm_data *ds1wm_data;
struct ds1wm_driver_data *plat;
struct resource *res;
int ret;
u8 inten;
if (!pdev)
return -ENODEV;
ds1wm_data = devm_kzalloc(&pdev->dev, sizeof(*ds1wm_data), GFP_KERNEL);
if (!ds1wm_data)
return -ENOMEM;
platform_set_drvdata(pdev, ds1wm_data);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENXIO;
ds1wm_data->map = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (!ds1wm_data->map)
return -ENOMEM;
ds1wm_data->pdev = pdev;
ds1wm_data->cell = mfd_get_cell(pdev);
if (!ds1wm_data->cell)
return -ENODEV;
plat = dev_get_platdata(&pdev->dev);
if (!plat)
return -ENODEV;
/* how many bits to shift register number to get register offset */
if (plat->bus_shift > 2) {
dev_err(&ds1wm_data->pdev->dev,
"illegal bus shift %d, not written",
ds1wm_data->bus_shift);
return -EINVAL;
}
ds1wm_data->bus_shift = plat->bus_shift;
/* make sure resource has space for 8 registers */
if ((8 << ds1wm_data->bus_shift) > resource_size(res)) {
dev_err(&ds1wm_data->pdev->dev,
"memory resource size %d to small, should be %d\n",
(int)resource_size(res),
8 << ds1wm_data->bus_shift);
return -EINVAL;
}
ds1wm_data->is_hw_big_endian = plat->is_hw_big_endian;
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res)
return -ENXIO;
ds1wm_data->irq = res->start;
ds1wm_data->int_en_reg_none = (plat->active_high ? DS1WM_INTEN_IAS : 0);
ds1wm_data->reset_recover_delay = plat->reset_recover_delay;
/* Mask interrupts, set IAS before claiming interrupt */
inten = ds1wm_read_register(ds1wm_data, DS1WM_INT_EN);
ds1wm_write_register(ds1wm_data,
DS1WM_INT_EN, ds1wm_data->int_en_reg_none);
if (res->flags & IORESOURCE_IRQ_HIGHEDGE)
irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_RISING);
if (res->flags & IORESOURCE_IRQ_LOWEDGE)
irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING);
if (res->flags & IORESOURCE_IRQ_HIGHLEVEL)
irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_LEVEL_HIGH);
if (res->flags & IORESOURCE_IRQ_LOWLEVEL)
irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_LEVEL_LOW);
ret = devm_request_irq(&pdev->dev, ds1wm_data->irq, ds1wm_isr,
IRQF_SHARED, "ds1wm", ds1wm_data);
if (ret) {
dev_err(&ds1wm_data->pdev->dev,
"devm_request_irq %d failed with errno %d\n",
ds1wm_data->irq,
ret);
return ret;
}
ds1wm_up(ds1wm_data);
ds1wm_master.data = (void *)ds1wm_data;
ret = w1_add_master_device(&ds1wm_master);
if (ret)
goto err;
dev_dbg(&ds1wm_data->pdev->dev,
"ds1wm: probe successful, IAS: %d, rec.delay: %d, clockrate: %d, bus-shift: %d, is Hw Big Endian: %d\n",
plat->active_high,
plat->reset_recover_delay,
plat->clock_rate,
ds1wm_data->bus_shift,
ds1wm_data->is_hw_big_endian);
return 0;
err:
ds1wm_down(ds1wm_data);
return ret;
}