| .. | .. |
|---|
| 19 | 19 | #include <linux/i2c.h> |
|---|
| 20 | 20 | #include <linux/module.h> |
|---|
| 21 | 21 | #include <linux/regmap.h> |
|---|
| 22 | +#include <linux/regulator/consumer.h> |
|---|
| 22 | 23 | #include <linux/slab.h> |
|---|
| 23 | 24 | #include <asm/unaligned.h> |
|---|
| 24 | 25 | |
|---|
| .. | .. |
|---|
| 59 | 60 | struct clk_si5341_output { |
|---|
| 60 | 61 | struct clk_hw hw; |
|---|
| 61 | 62 | struct clk_si5341 *data; |
|---|
| 63 | + struct regulator *vddo_reg; |
|---|
| 62 | 64 | u8 index; |
|---|
| 63 | 65 | }; |
|---|
| 64 | 66 | #define to_clk_si5341_output(_hw) \ |
|---|
| .. | .. |
|---|
| 84 | 86 | struct clk_si5341_output_config { |
|---|
| 85 | 87 | u8 out_format_drv_bits; |
|---|
| 86 | 88 | u8 out_cm_ampl_bits; |
|---|
| 89 | + u8 vdd_sel_bits; |
|---|
| 87 | 90 | bool synth_master; |
|---|
| 88 | 91 | bool always_on; |
|---|
| 89 | 92 | }; |
|---|
| .. | .. |
|---|
| 135 | 138 | #define SI5341_OUT_MUX_SEL(output) (SI5341_OUT_CONFIG(output) + 3) |
|---|
| 136 | 139 | #define SI5341_OUT_R_REG(output) \ |
|---|
| 137 | 140 | ((output)->data->reg_rdiv_offset[(output)->index]) |
|---|
| 141 | + |
|---|
| 142 | +#define SI5341_OUT_MUX_VDD_SEL_MASK 0x38 |
|---|
| 138 | 143 | |
|---|
| 139 | 144 | /* Synthesize N divider */ |
|---|
| 140 | 145 | #define SI5341_SYNTH_N_NUM(x) (0x0302 + ((x) * 11)) |
|---|
| .. | .. |
|---|
| 1250 | 1255 | .volatile_table = &si5341_regmap_volatile, |
|---|
| 1251 | 1256 | }; |
|---|
| 1252 | 1257 | |
|---|
| 1253 | | -static int si5341_dt_parse_dt(struct i2c_client *client, |
|---|
| 1254 | | - struct clk_si5341_output_config *config) |
|---|
| 1258 | +static int si5341_dt_parse_dt(struct clk_si5341 *data, |
|---|
| 1259 | + struct clk_si5341_output_config *config) |
|---|
| 1255 | 1260 | { |
|---|
| 1256 | 1261 | struct device_node *child; |
|---|
| 1257 | | - struct device_node *np = client->dev.of_node; |
|---|
| 1262 | + struct device_node *np = data->i2c_client->dev.of_node; |
|---|
| 1258 | 1263 | u32 num; |
|---|
| 1259 | 1264 | u32 val; |
|---|
| 1260 | 1265 | |
|---|
| .. | .. |
|---|
| 1263 | 1268 | |
|---|
| 1264 | 1269 | for_each_child_of_node(np, child) { |
|---|
| 1265 | 1270 | if (of_property_read_u32(child, "reg", &num)) { |
|---|
| 1266 | | - dev_err(&client->dev, "missing reg property of %s\n", |
|---|
| 1271 | + dev_err(&data->i2c_client->dev, "missing reg property of %s\n", |
|---|
| 1267 | 1272 | child->name); |
|---|
| 1268 | 1273 | goto put_child; |
|---|
| 1269 | 1274 | } |
|---|
| 1270 | 1275 | |
|---|
| 1271 | 1276 | if (num >= SI5341_MAX_NUM_OUTPUTS) { |
|---|
| 1272 | | - dev_err(&client->dev, "invalid clkout %d\n", num); |
|---|
| 1277 | + dev_err(&data->i2c_client->dev, "invalid clkout %d\n", num); |
|---|
| 1273 | 1278 | goto put_child; |
|---|
| 1274 | 1279 | } |
|---|
| 1275 | 1280 | |
|---|
| .. | .. |
|---|
| 1288 | 1293 | config[num].out_format_drv_bits |= 0xc0; |
|---|
| 1289 | 1294 | break; |
|---|
| 1290 | 1295 | default: |
|---|
| 1291 | | - dev_err(&client->dev, |
|---|
| 1296 | + dev_err(&data->i2c_client->dev, |
|---|
| 1292 | 1297 | "invalid silabs,format %u for %u\n", |
|---|
| 1293 | 1298 | val, num); |
|---|
| 1294 | 1299 | goto put_child; |
|---|
| .. | .. |
|---|
| 1301 | 1306 | |
|---|
| 1302 | 1307 | if (!of_property_read_u32(child, "silabs,common-mode", &val)) { |
|---|
| 1303 | 1308 | if (val > 0xf) { |
|---|
| 1304 | | - dev_err(&client->dev, |
|---|
| 1309 | + dev_err(&data->i2c_client->dev, |
|---|
| 1305 | 1310 | "invalid silabs,common-mode %u\n", |
|---|
| 1306 | 1311 | val); |
|---|
| 1307 | 1312 | goto put_child; |
|---|
| .. | .. |
|---|
| 1312 | 1317 | |
|---|
| 1313 | 1318 | if (!of_property_read_u32(child, "silabs,amplitude", &val)) { |
|---|
| 1314 | 1319 | if (val > 0xf) { |
|---|
| 1315 | | - dev_err(&client->dev, |
|---|
| 1320 | + dev_err(&data->i2c_client->dev, |
|---|
| 1316 | 1321 | "invalid silabs,amplitude %u\n", |
|---|
| 1317 | 1322 | val); |
|---|
| 1318 | 1323 | goto put_child; |
|---|
| .. | .. |
|---|
| 1329 | 1334 | |
|---|
| 1330 | 1335 | config[num].always_on = |
|---|
| 1331 | 1336 | of_property_read_bool(child, "always-on"); |
|---|
| 1337 | + |
|---|
| 1338 | + config[num].vdd_sel_bits = 0x08; |
|---|
| 1339 | + if (data->clk[num].vddo_reg) { |
|---|
| 1340 | + int vdd = regulator_get_voltage(data->clk[num].vddo_reg); |
|---|
| 1341 | + |
|---|
| 1342 | + switch (vdd) { |
|---|
| 1343 | + case 3300000: |
|---|
| 1344 | + config[num].vdd_sel_bits |= 0 << 4; |
|---|
| 1345 | + break; |
|---|
| 1346 | + case 1800000: |
|---|
| 1347 | + config[num].vdd_sel_bits |= 1 << 4; |
|---|
| 1348 | + break; |
|---|
| 1349 | + case 2500000: |
|---|
| 1350 | + config[num].vdd_sel_bits |= 2 << 4; |
|---|
| 1351 | + break; |
|---|
| 1352 | + default: |
|---|
| 1353 | + dev_err(&data->i2c_client->dev, |
|---|
| 1354 | + "unsupported vddo voltage %d for %s\n", |
|---|
| 1355 | + vdd, child->name); |
|---|
| 1356 | + goto put_child; |
|---|
| 1357 | + } |
|---|
| 1358 | + } else { |
|---|
| 1359 | + /* chip seems to default to 2.5V when not set */ |
|---|
| 1360 | + dev_warn(&data->i2c_client->dev, |
|---|
| 1361 | + "no regulator set, defaulting vdd_sel to 2.5V for %s\n", |
|---|
| 1362 | + child->name); |
|---|
| 1363 | + config[num].vdd_sel_bits |= 2 << 4; |
|---|
| 1364 | + } |
|---|
| 1332 | 1365 | } |
|---|
| 1333 | 1366 | |
|---|
| 1334 | 1367 | return 0; |
|---|
| .. | .. |
|---|
| 1417 | 1450 | return res; |
|---|
| 1418 | 1451 | } |
|---|
| 1419 | 1452 | |
|---|
| 1453 | +static ssize_t input_present_show(struct device *dev, |
|---|
| 1454 | + struct device_attribute *attr, |
|---|
| 1455 | + char *buf) |
|---|
| 1456 | +{ |
|---|
| 1457 | + struct clk_si5341 *data = dev_get_drvdata(dev); |
|---|
| 1458 | + u32 status; |
|---|
| 1459 | + int res = regmap_read(data->regmap, SI5341_STATUS, &status); |
|---|
| 1460 | + |
|---|
| 1461 | + if (res < 0) |
|---|
| 1462 | + return res; |
|---|
| 1463 | + res = !(status & SI5341_STATUS_LOSREF); |
|---|
| 1464 | + return snprintf(buf, PAGE_SIZE, "%d\n", res); |
|---|
| 1465 | +} |
|---|
| 1466 | +static DEVICE_ATTR_RO(input_present); |
|---|
| 1467 | + |
|---|
| 1468 | +static ssize_t input_present_sticky_show(struct device *dev, |
|---|
| 1469 | + struct device_attribute *attr, |
|---|
| 1470 | + char *buf) |
|---|
| 1471 | +{ |
|---|
| 1472 | + struct clk_si5341 *data = dev_get_drvdata(dev); |
|---|
| 1473 | + u32 status; |
|---|
| 1474 | + int res = regmap_read(data->regmap, SI5341_STATUS_STICKY, &status); |
|---|
| 1475 | + |
|---|
| 1476 | + if (res < 0) |
|---|
| 1477 | + return res; |
|---|
| 1478 | + res = !(status & SI5341_STATUS_LOSREF); |
|---|
| 1479 | + return snprintf(buf, PAGE_SIZE, "%d\n", res); |
|---|
| 1480 | +} |
|---|
| 1481 | +static DEVICE_ATTR_RO(input_present_sticky); |
|---|
| 1482 | + |
|---|
| 1483 | +static ssize_t pll_locked_show(struct device *dev, |
|---|
| 1484 | + struct device_attribute *attr, |
|---|
| 1485 | + char *buf) |
|---|
| 1486 | +{ |
|---|
| 1487 | + struct clk_si5341 *data = dev_get_drvdata(dev); |
|---|
| 1488 | + u32 status; |
|---|
| 1489 | + int res = regmap_read(data->regmap, SI5341_STATUS, &status); |
|---|
| 1490 | + |
|---|
| 1491 | + if (res < 0) |
|---|
| 1492 | + return res; |
|---|
| 1493 | + res = !(status & SI5341_STATUS_LOL); |
|---|
| 1494 | + return snprintf(buf, PAGE_SIZE, "%d\n", res); |
|---|
| 1495 | +} |
|---|
| 1496 | +static DEVICE_ATTR_RO(pll_locked); |
|---|
| 1497 | + |
|---|
| 1498 | +static ssize_t pll_locked_sticky_show(struct device *dev, |
|---|
| 1499 | + struct device_attribute *attr, |
|---|
| 1500 | + char *buf) |
|---|
| 1501 | +{ |
|---|
| 1502 | + struct clk_si5341 *data = dev_get_drvdata(dev); |
|---|
| 1503 | + u32 status; |
|---|
| 1504 | + int res = regmap_read(data->regmap, SI5341_STATUS_STICKY, &status); |
|---|
| 1505 | + |
|---|
| 1506 | + if (res < 0) |
|---|
| 1507 | + return res; |
|---|
| 1508 | + res = !(status & SI5341_STATUS_LOL); |
|---|
| 1509 | + return snprintf(buf, PAGE_SIZE, "%d\n", res); |
|---|
| 1510 | +} |
|---|
| 1511 | +static DEVICE_ATTR_RO(pll_locked_sticky); |
|---|
| 1512 | + |
|---|
| 1513 | +static ssize_t clear_sticky_store(struct device *dev, |
|---|
| 1514 | + struct device_attribute *attr, |
|---|
| 1515 | + const char *buf, size_t count) |
|---|
| 1516 | +{ |
|---|
| 1517 | + struct clk_si5341 *data = dev_get_drvdata(dev); |
|---|
| 1518 | + long val; |
|---|
| 1519 | + |
|---|
| 1520 | + if (kstrtol(buf, 10, &val)) |
|---|
| 1521 | + return -EINVAL; |
|---|
| 1522 | + if (val) { |
|---|
| 1523 | + int res = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0); |
|---|
| 1524 | + |
|---|
| 1525 | + if (res < 0) |
|---|
| 1526 | + return res; |
|---|
| 1527 | + } |
|---|
| 1528 | + return count; |
|---|
| 1529 | +} |
|---|
| 1530 | +static DEVICE_ATTR_WO(clear_sticky); |
|---|
| 1531 | + |
|---|
| 1532 | +static const struct attribute *si5341_attributes[] = { |
|---|
| 1533 | + &dev_attr_input_present.attr, |
|---|
| 1534 | + &dev_attr_input_present_sticky.attr, |
|---|
| 1535 | + &dev_attr_pll_locked.attr, |
|---|
| 1536 | + &dev_attr_pll_locked_sticky.attr, |
|---|
| 1537 | + &dev_attr_clear_sticky.attr, |
|---|
| 1538 | + NULL |
|---|
| 1539 | +}; |
|---|
| 1540 | + |
|---|
| 1420 | 1541 | static int si5341_probe(struct i2c_client *client, |
|---|
| 1421 | 1542 | const struct i2c_device_id *id) |
|---|
| 1422 | 1543 | { |
|---|
| .. | .. |
|---|
| 1424 | 1545 | struct clk_init_data init; |
|---|
| 1425 | 1546 | struct clk *input; |
|---|
| 1426 | 1547 | const char *root_clock_name; |
|---|
| 1427 | | - const char *synth_clock_names[SI5341_NUM_SYNTH]; |
|---|
| 1548 | + const char *synth_clock_names[SI5341_NUM_SYNTH] = { NULL }; |
|---|
| 1428 | 1549 | int err; |
|---|
| 1429 | 1550 | unsigned int i; |
|---|
| 1430 | 1551 | struct clk_si5341_output_config config[SI5341_MAX_NUM_OUTPUTS]; |
|---|
| .. | .. |
|---|
| 1454 | 1575 | } |
|---|
| 1455 | 1576 | } |
|---|
| 1456 | 1577 | |
|---|
| 1457 | | - err = si5341_dt_parse_dt(client, config); |
|---|
| 1578 | + for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) { |
|---|
| 1579 | + char reg_name[10]; |
|---|
| 1580 | + |
|---|
| 1581 | + snprintf(reg_name, sizeof(reg_name), "vddo%d", i); |
|---|
| 1582 | + data->clk[i].vddo_reg = devm_regulator_get_optional( |
|---|
| 1583 | + &client->dev, reg_name); |
|---|
| 1584 | + if (IS_ERR(data->clk[i].vddo_reg)) { |
|---|
| 1585 | + err = PTR_ERR(data->clk[i].vddo_reg); |
|---|
| 1586 | + data->clk[i].vddo_reg = NULL; |
|---|
| 1587 | + if (err == -ENODEV) |
|---|
| 1588 | + continue; |
|---|
| 1589 | + goto cleanup; |
|---|
| 1590 | + } else { |
|---|
| 1591 | + err = regulator_enable(data->clk[i].vddo_reg); |
|---|
| 1592 | + if (err) { |
|---|
| 1593 | + dev_err(&client->dev, |
|---|
| 1594 | + "failed to enable %s regulator: %d\n", |
|---|
| 1595 | + reg_name, err); |
|---|
| 1596 | + data->clk[i].vddo_reg = NULL; |
|---|
| 1597 | + goto cleanup; |
|---|
| 1598 | + } |
|---|
| 1599 | + } |
|---|
| 1600 | + } |
|---|
| 1601 | + |
|---|
| 1602 | + err = si5341_dt_parse_dt(data, config); |
|---|
| 1458 | 1603 | if (err) |
|---|
| 1459 | | - return err; |
|---|
| 1604 | + goto cleanup; |
|---|
| 1460 | 1605 | |
|---|
| 1461 | 1606 | if (of_property_read_string(client->dev.of_node, "clock-output-names", |
|---|
| 1462 | 1607 | &init.name)) |
|---|
| .. | .. |
|---|
| 1464 | 1609 | root_clock_name = init.name; |
|---|
| 1465 | 1610 | |
|---|
| 1466 | 1611 | data->regmap = devm_regmap_init_i2c(client, &si5341_regmap_config); |
|---|
| 1467 | | - if (IS_ERR(data->regmap)) |
|---|
| 1468 | | - return PTR_ERR(data->regmap); |
|---|
| 1612 | + if (IS_ERR(data->regmap)) { |
|---|
| 1613 | + err = PTR_ERR(data->regmap); |
|---|
| 1614 | + goto cleanup; |
|---|
| 1615 | + } |
|---|
| 1469 | 1616 | |
|---|
| 1470 | 1617 | i2c_set_clientdata(client, data); |
|---|
| 1471 | 1618 | |
|---|
| 1472 | 1619 | err = si5341_probe_chip_id(data); |
|---|
| 1473 | 1620 | if (err < 0) |
|---|
| 1474 | | - return err; |
|---|
| 1621 | + goto cleanup; |
|---|
| 1475 | 1622 | |
|---|
| 1476 | 1623 | if (of_property_read_bool(client->dev.of_node, "silabs,reprogram")) { |
|---|
| 1477 | 1624 | initialization_required = true; |
|---|
| 1478 | 1625 | } else { |
|---|
| 1479 | 1626 | err = si5341_is_programmed_already(data); |
|---|
| 1480 | 1627 | if (err < 0) |
|---|
| 1481 | | - return err; |
|---|
| 1628 | + goto cleanup; |
|---|
| 1482 | 1629 | |
|---|
| 1483 | 1630 | initialization_required = !err; |
|---|
| 1484 | 1631 | } |
|---|
| .. | .. |
|---|
| 1487 | 1634 | /* Populate the regmap cache in preparation for "cache only" */ |
|---|
| 1488 | 1635 | err = si5341_read_settings(data); |
|---|
| 1489 | 1636 | if (err < 0) |
|---|
| 1490 | | - return err; |
|---|
| 1637 | + goto cleanup; |
|---|
| 1491 | 1638 | |
|---|
| 1492 | 1639 | err = si5341_send_preamble(data); |
|---|
| 1493 | 1640 | if (err < 0) |
|---|
| 1494 | | - return err; |
|---|
| 1641 | + goto cleanup; |
|---|
| 1495 | 1642 | |
|---|
| 1496 | 1643 | /* |
|---|
| 1497 | 1644 | * We intend to send all 'final' register values in a single |
|---|
| .. | .. |
|---|
| 1504 | 1651 | err = si5341_write_multiple(data, si5341_reg_defaults, |
|---|
| 1505 | 1652 | ARRAY_SIZE(si5341_reg_defaults)); |
|---|
| 1506 | 1653 | if (err < 0) |
|---|
| 1507 | | - return err; |
|---|
| 1654 | + goto cleanup; |
|---|
| 1508 | 1655 | } |
|---|
| 1509 | 1656 | |
|---|
| 1510 | 1657 | /* Input must be up and running at this point */ |
|---|
| 1511 | 1658 | err = si5341_clk_select_active_input(data); |
|---|
| 1512 | 1659 | if (err < 0) |
|---|
| 1513 | | - return err; |
|---|
| 1660 | + goto cleanup; |
|---|
| 1514 | 1661 | |
|---|
| 1515 | 1662 | if (initialization_required) { |
|---|
| 1516 | 1663 | /* PLL configuration is required */ |
|---|
| 1517 | 1664 | err = si5341_initialize_pll(data); |
|---|
| 1518 | 1665 | if (err < 0) |
|---|
| 1519 | | - return err; |
|---|
| 1666 | + goto cleanup; |
|---|
| 1520 | 1667 | } |
|---|
| 1521 | 1668 | |
|---|
| 1522 | 1669 | /* Register the PLL */ |
|---|
| .. | .. |
|---|
| 1529 | 1676 | err = devm_clk_hw_register(&client->dev, &data->hw); |
|---|
| 1530 | 1677 | if (err) { |
|---|
| 1531 | 1678 | dev_err(&client->dev, "clock registration failed\n"); |
|---|
| 1532 | | - return err; |
|---|
| 1679 | + goto cleanup; |
|---|
| 1533 | 1680 | } |
|---|
| 1534 | 1681 | |
|---|
| 1535 | 1682 | init.num_parents = 1; |
|---|
| .. | .. |
|---|
| 1538 | 1685 | for (i = 0; i < data->num_synth; ++i) { |
|---|
| 1539 | 1686 | synth_clock_names[i] = devm_kasprintf(&client->dev, GFP_KERNEL, |
|---|
| 1540 | 1687 | "%s.N%u", client->dev.of_node->name, i); |
|---|
| 1688 | + if (!synth_clock_names[i]) { |
|---|
| 1689 | + err = -ENOMEM; |
|---|
| 1690 | + goto free_clk_names; |
|---|
| 1691 | + } |
|---|
| 1541 | 1692 | init.name = synth_clock_names[i]; |
|---|
| 1542 | 1693 | data->synth[i].index = i; |
|---|
| 1543 | 1694 | data->synth[i].data = data; |
|---|
| .. | .. |
|---|
| 1546 | 1697 | if (err) { |
|---|
| 1547 | 1698 | dev_err(&client->dev, |
|---|
| 1548 | 1699 | "synth N%u registration failed\n", i); |
|---|
| 1700 | + goto free_clk_names; |
|---|
| 1549 | 1701 | } |
|---|
| 1550 | 1702 | } |
|---|
| 1551 | 1703 | |
|---|
| .. | .. |
|---|
| 1555 | 1707 | for (i = 0; i < data->num_outputs; ++i) { |
|---|
| 1556 | 1708 | init.name = kasprintf(GFP_KERNEL, "%s.%d", |
|---|
| 1557 | 1709 | client->dev.of_node->name, i); |
|---|
| 1710 | + if (!init.name) { |
|---|
| 1711 | + err = -ENOMEM; |
|---|
| 1712 | + goto free_clk_names; |
|---|
| 1713 | + } |
|---|
| 1558 | 1714 | init.flags = config[i].synth_master ? CLK_SET_RATE_PARENT : 0; |
|---|
| 1559 | 1715 | data->clk[i].index = i; |
|---|
| 1560 | 1716 | data->clk[i].data = data; |
|---|
| .. | .. |
|---|
| 1566 | 1722 | regmap_write(data->regmap, |
|---|
| 1567 | 1723 | SI5341_OUT_CM(&data->clk[i]), |
|---|
| 1568 | 1724 | config[i].out_cm_ampl_bits); |
|---|
| 1725 | + regmap_update_bits(data->regmap, |
|---|
| 1726 | + SI5341_OUT_MUX_SEL(&data->clk[i]), |
|---|
| 1727 | + SI5341_OUT_MUX_VDD_SEL_MASK, |
|---|
| 1728 | + config[i].vdd_sel_bits); |
|---|
| 1569 | 1729 | } |
|---|
| 1570 | 1730 | err = devm_clk_hw_register(&client->dev, &data->clk[i].hw); |
|---|
| 1571 | 1731 | kfree(init.name); /* clock framework made a copy of the name */ |
|---|
| 1572 | 1732 | if (err) { |
|---|
| 1573 | 1733 | dev_err(&client->dev, |
|---|
| 1574 | 1734 | "output %u registration failed\n", i); |
|---|
| 1575 | | - return err; |
|---|
| 1735 | + goto free_clk_names; |
|---|
| 1576 | 1736 | } |
|---|
| 1577 | 1737 | if (config[i].always_on) |
|---|
| 1578 | 1738 | clk_prepare(data->clk[i].hw.clk); |
|---|
| .. | .. |
|---|
| 1582 | 1742 | data); |
|---|
| 1583 | 1743 | if (err) { |
|---|
| 1584 | 1744 | dev_err(&client->dev, "unable to add clk provider\n"); |
|---|
| 1585 | | - return err; |
|---|
| 1745 | + goto free_clk_names; |
|---|
| 1586 | 1746 | } |
|---|
| 1587 | 1747 | |
|---|
| 1588 | 1748 | if (initialization_required) { |
|---|
| .. | .. |
|---|
| 1590 | 1750 | regcache_cache_only(data->regmap, false); |
|---|
| 1591 | 1751 | err = regcache_sync(data->regmap); |
|---|
| 1592 | 1752 | if (err < 0) |
|---|
| 1593 | | - return err; |
|---|
| 1753 | + goto free_clk_names; |
|---|
| 1594 | 1754 | |
|---|
| 1595 | 1755 | err = si5341_finalize_defaults(data); |
|---|
| 1596 | 1756 | if (err < 0) |
|---|
| 1597 | | - return err; |
|---|
| 1757 | + goto free_clk_names; |
|---|
| 1598 | 1758 | } |
|---|
| 1599 | 1759 | |
|---|
| 1600 | 1760 | /* wait for device to report input clock present and PLL lock */ |
|---|
| .. | .. |
|---|
| 1603 | 1763 | 10000, 250000); |
|---|
| 1604 | 1764 | if (err) { |
|---|
| 1605 | 1765 | dev_err(&client->dev, "Error waiting for input clock or PLL lock\n"); |
|---|
| 1606 | | - return err; |
|---|
| 1766 | + goto free_clk_names; |
|---|
| 1607 | 1767 | } |
|---|
| 1608 | 1768 | |
|---|
| 1609 | 1769 | /* clear sticky alarm bits from initialization */ |
|---|
| 1610 | 1770 | err = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0); |
|---|
| 1611 | 1771 | if (err) { |
|---|
| 1612 | 1772 | dev_err(&client->dev, "unable to clear sticky status\n"); |
|---|
| 1613 | | - return err; |
|---|
| 1773 | + goto free_clk_names; |
|---|
| 1614 | 1774 | } |
|---|
| 1615 | 1775 | |
|---|
| 1776 | + err = sysfs_create_files(&client->dev.kobj, si5341_attributes); |
|---|
| 1777 | + if (err) |
|---|
| 1778 | + dev_err(&client->dev, "unable to create sysfs files\n"); |
|---|
| 1779 | + |
|---|
| 1780 | +free_clk_names: |
|---|
| 1616 | 1781 | /* Free the names, clk framework makes copies */ |
|---|
| 1617 | 1782 | for (i = 0; i < data->num_synth; ++i) |
|---|
| 1618 | 1783 | devm_kfree(&client->dev, (void *)synth_clock_names[i]); |
|---|
| 1784 | + |
|---|
| 1785 | +cleanup: |
|---|
| 1786 | + if (err) { |
|---|
| 1787 | + for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) { |
|---|
| 1788 | + if (data->clk[i].vddo_reg) |
|---|
| 1789 | + regulator_disable(data->clk[i].vddo_reg); |
|---|
| 1790 | + } |
|---|
| 1791 | + } |
|---|
| 1792 | + return err; |
|---|
| 1793 | +} |
|---|
| 1794 | + |
|---|
| 1795 | +static int si5341_remove(struct i2c_client *client) |
|---|
| 1796 | +{ |
|---|
| 1797 | + struct clk_si5341 *data = i2c_get_clientdata(client); |
|---|
| 1798 | + int i; |
|---|
| 1799 | + |
|---|
| 1800 | + sysfs_remove_files(&client->dev.kobj, si5341_attributes); |
|---|
| 1801 | + |
|---|
| 1802 | + for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) { |
|---|
| 1803 | + if (data->clk[i].vddo_reg) |
|---|
| 1804 | + regulator_disable(data->clk[i].vddo_reg); |
|---|
| 1805 | + } |
|---|
| 1619 | 1806 | |
|---|
| 1620 | 1807 | return 0; |
|---|
| 1621 | 1808 | } |
|---|
| .. | .. |
|---|
| 1646 | 1833 | .of_match_table = clk_si5341_of_match, |
|---|
| 1647 | 1834 | }, |
|---|
| 1648 | 1835 | .probe = si5341_probe, |
|---|
| 1836 | + .remove = si5341_remove, |
|---|
| 1649 | 1837 | .id_table = si5341_id, |
|---|
| 1650 | 1838 | }; |
|---|
| 1651 | 1839 | module_i2c_driver(si5341_driver); |
|---|