| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* linux/drivers/mfd/sm501.c |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright (C) 2006 Simtec Electronics |
|---|
| 4 | 5 | * Ben Dooks <ben@simtec.co.uk> |
|---|
| 5 | 6 | * Vincent Sanders <vince@simtec.co.uk> |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 9 | | - * published by the Free Software Foundation. |
|---|
| 10 | 7 | * |
|---|
| 11 | 8 | * SM501 MFD driver |
|---|
| 12 | 9 | */ |
|---|
| .. | .. |
|---|
| 20 | 17 | #include <linux/platform_device.h> |
|---|
| 21 | 18 | #include <linux/pci.h> |
|---|
| 22 | 19 | #include <linux/platform_data/i2c-gpio.h> |
|---|
| 20 | +#include <linux/gpio/driver.h> |
|---|
| 23 | 21 | #include <linux/gpio/machine.h> |
|---|
| 24 | 22 | #include <linux/slab.h> |
|---|
| 25 | 23 | |
|---|
| .. | .. |
|---|
| 1088 | 1086 | iounmap(gpio->regs); |
|---|
| 1089 | 1087 | |
|---|
| 1090 | 1088 | err_claimed: |
|---|
| 1091 | | - release_resource(gpio->regs_res); |
|---|
| 1092 | | - kfree(gpio->regs_res); |
|---|
| 1089 | + release_mem_region(iobase, 0x20); |
|---|
| 1093 | 1090 | |
|---|
| 1094 | 1091 | return ret; |
|---|
| 1095 | 1092 | } |
|---|
| .. | .. |
|---|
| 1097 | 1094 | static void sm501_gpio_remove(struct sm501_devdata *sm) |
|---|
| 1098 | 1095 | { |
|---|
| 1099 | 1096 | struct sm501_gpio *gpio = &sm->gpio; |
|---|
| 1097 | + resource_size_t iobase = sm->io_res->start + SM501_GPIO; |
|---|
| 1100 | 1098 | |
|---|
| 1101 | 1099 | if (!sm->gpio.registered) |
|---|
| 1102 | 1100 | return; |
|---|
| .. | .. |
|---|
| 1105 | 1103 | gpiochip_remove(&gpio->high.gpio); |
|---|
| 1106 | 1104 | |
|---|
| 1107 | 1105 | iounmap(gpio->regs); |
|---|
| 1108 | | - release_resource(gpio->regs_res); |
|---|
| 1109 | | - kfree(gpio->regs_res); |
|---|
| 1106 | + release_mem_region(iobase, 0x20); |
|---|
| 1110 | 1107 | } |
|---|
| 1111 | 1108 | |
|---|
| 1112 | 1109 | static inline int sm501_gpio_isregistered(struct sm501_devdata *sm) |
|---|
| .. | .. |
|---|
| 1142 | 1139 | return -ENOMEM; |
|---|
| 1143 | 1140 | |
|---|
| 1144 | 1141 | /* Create a gpiod lookup using gpiochip-local offsets */ |
|---|
| 1145 | | - lookup = devm_kzalloc(&pdev->dev, |
|---|
| 1146 | | - sizeof(*lookup) + 3 * sizeof(struct gpiod_lookup), |
|---|
| 1142 | + lookup = devm_kzalloc(&pdev->dev, struct_size(lookup, table, 3), |
|---|
| 1147 | 1143 | GFP_KERNEL); |
|---|
| 1148 | 1144 | if (!lookup) |
|---|
| 1149 | 1145 | return -ENOMEM; |
|---|
| 1150 | 1146 | |
|---|
| 1151 | 1147 | lookup->dev_id = "i2c-gpio"; |
|---|
| 1152 | | - if (iic->pin_sda < 32) |
|---|
| 1153 | | - lookup->table[0].chip_label = "SM501-LOW"; |
|---|
| 1154 | | - else |
|---|
| 1155 | | - lookup->table[0].chip_label = "SM501-HIGH"; |
|---|
| 1156 | | - lookup->table[0].chip_hwnum = iic->pin_sda % 32; |
|---|
| 1157 | | - lookup->table[0].con_id = NULL; |
|---|
| 1158 | | - lookup->table[0].idx = 0; |
|---|
| 1159 | | - lookup->table[0].flags = GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN; |
|---|
| 1160 | | - if (iic->pin_scl < 32) |
|---|
| 1161 | | - lookup->table[1].chip_label = "SM501-LOW"; |
|---|
| 1162 | | - else |
|---|
| 1163 | | - lookup->table[1].chip_label = "SM501-HIGH"; |
|---|
| 1164 | | - lookup->table[1].chip_hwnum = iic->pin_scl % 32; |
|---|
| 1165 | | - lookup->table[1].con_id = NULL; |
|---|
| 1166 | | - lookup->table[1].idx = 1; |
|---|
| 1167 | | - lookup->table[1].flags = GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN; |
|---|
| 1148 | + lookup->table[0] = (struct gpiod_lookup) |
|---|
| 1149 | + GPIO_LOOKUP_IDX(iic->pin_sda < 32 ? "SM501-LOW" : "SM501-HIGH", |
|---|
| 1150 | + iic->pin_sda % 32, NULL, 0, |
|---|
| 1151 | + GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN); |
|---|
| 1152 | + lookup->table[1] = (struct gpiod_lookup) |
|---|
| 1153 | + GPIO_LOOKUP_IDX(iic->pin_scl < 32 ? "SM501-LOW" : "SM501-HIGH", |
|---|
| 1154 | + iic->pin_scl % 32, NULL, 1, |
|---|
| 1155 | + GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN); |
|---|
| 1168 | 1156 | gpiod_add_lookup_table(lookup); |
|---|
| 1169 | 1157 | |
|---|
| 1170 | 1158 | icd = dev_get_platdata(&pdev->dev); |
|---|
| .. | .. |
|---|
| 1398 | 1386 | sm->platdata = dev_get_platdata(&dev->dev); |
|---|
| 1399 | 1387 | |
|---|
| 1400 | 1388 | ret = platform_get_irq(dev, 0); |
|---|
| 1401 | | - if (ret < 0) { |
|---|
| 1402 | | - dev_err(&dev->dev, "failed to get irq resource\n"); |
|---|
| 1389 | + if (ret < 0) |
|---|
| 1403 | 1390 | goto err_res; |
|---|
| 1404 | | - } |
|---|
| 1405 | 1391 | sm->irq = ret; |
|---|
| 1406 | 1392 | |
|---|
| 1407 | 1393 | sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1); |
|---|
| .. | .. |
|---|
| 1438 | 1424 | err_unmap: |
|---|
| 1439 | 1425 | iounmap(sm->regs); |
|---|
| 1440 | 1426 | err_claim: |
|---|
| 1441 | | - release_resource(sm->regs_claim); |
|---|
| 1442 | | - kfree(sm->regs_claim); |
|---|
| 1427 | + release_mem_region(sm->io_res->start, 0x100); |
|---|
| 1443 | 1428 | err_res: |
|---|
| 1444 | 1429 | kfree(sm); |
|---|
| 1445 | 1430 | err1: |
|---|
| .. | .. |
|---|
| 1648 | 1633 | return 0; |
|---|
| 1649 | 1634 | |
|---|
| 1650 | 1635 | err4: |
|---|
| 1651 | | - release_resource(sm->regs_claim); |
|---|
| 1652 | | - kfree(sm->regs_claim); |
|---|
| 1636 | + release_mem_region(sm->io_res->start, 0x100); |
|---|
| 1653 | 1637 | err3: |
|---|
| 1654 | 1638 | pci_disable_device(dev); |
|---|
| 1655 | 1639 | err2: |
|---|
| .. | .. |
|---|
| 1684 | 1668 | sm501_dev_remove(sm); |
|---|
| 1685 | 1669 | iounmap(sm->regs); |
|---|
| 1686 | 1670 | |
|---|
| 1687 | | - release_resource(sm->regs_claim); |
|---|
| 1688 | | - kfree(sm->regs_claim); |
|---|
| 1671 | + release_mem_region(sm->io_res->start, 0x100); |
|---|
| 1689 | 1672 | |
|---|
| 1690 | 1673 | pci_disable_device(dev); |
|---|
| 1691 | 1674 | } |
|---|
| .. | .. |
|---|
| 1697 | 1680 | sm501_dev_remove(sm); |
|---|
| 1698 | 1681 | iounmap(sm->regs); |
|---|
| 1699 | 1682 | |
|---|
| 1700 | | - release_resource(sm->regs_claim); |
|---|
| 1701 | | - kfree(sm->regs_claim); |
|---|
| 1683 | + release_mem_region(sm->io_res->start, 0x100); |
|---|
| 1702 | 1684 | |
|---|
| 1703 | 1685 | return 0; |
|---|
| 1704 | 1686 | } |
|---|
| .. | .. |
|---|
| 1738 | 1720 | |
|---|
| 1739 | 1721 | static int __init sm501_base_init(void) |
|---|
| 1740 | 1722 | { |
|---|
| 1741 | | - platform_driver_register(&sm501_plat_driver); |
|---|
| 1723 | + int ret; |
|---|
| 1724 | + |
|---|
| 1725 | + ret = platform_driver_register(&sm501_plat_driver); |
|---|
| 1726 | + if (ret < 0) |
|---|
| 1727 | + return ret; |
|---|
| 1728 | + |
|---|
| 1742 | 1729 | return pci_register_driver(&sm501_pci_driver); |
|---|
| 1743 | 1730 | } |
|---|
| 1744 | 1731 | |
|---|