Commit 283131d2 authored by David S. Miller's avatar David S. Miller

Merge tag 'nfc-next-4.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/nfc-next

Samuel Ortiz says:

====================
NFC 4.13 pull request

This is the NFC pull requesy for 4.13. We have:

- A conversion to unified device and GPIO APIs for the
  fdp, pn544, and st{21,-nci} drivers.
- A fix for NFC device IDs allocation.
- A fix for the nfcmrvl driver firmware download mechanism.
- A trf7970a DT and GPIO cleanup and clock setting fix.
- A few fixes for potential overflows in the digital and LLCP code.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9d46b770 bd751808
...@@ -13,14 +13,10 @@ Optional SoC Specific Properties: ...@@ -13,14 +13,10 @@ Optional SoC Specific Properties:
- pinctrl-names: Contains only one value - "default". - pinctrl-names: Contains only one value - "default".
- pintctrl-0: Specifies the pin control groups used for this controller. - pintctrl-0: Specifies the pin control groups used for this controller.
- autosuspend-delay: Specify autosuspend delay in milliseconds. - autosuspend-delay: Specify autosuspend delay in milliseconds.
- vin-voltage-override: Specify voltage of VIN pin in microvolts.
- irq-status-read-quirk: Specify that the trf7970a being used has the - irq-status-read-quirk: Specify that the trf7970a being used has the
"IRQ Status Read" erratum. "IRQ Status Read" erratum.
- en2-rf-quirk: Specify that the trf7970a being used has the "EN2 RF" - en2-rf-quirk: Specify that the trf7970a being used has the "EN2 RF"
erratum. erratum.
- t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum
where an extra byte is returned by Read Multiple Block commands issued
to Type 5 tags.
- vdd-io-supply: Regulator specifying voltage for vdd-io - vdd-io-supply: Regulator specifying voltage for vdd-io
- clock-frequency: Set to specify that the input frequency to the trf7970a is 13560000Hz or 27120000Hz - clock-frequency: Set to specify that the input frequency to the trf7970a is 13560000Hz or 27120000Hz
...@@ -37,15 +33,13 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1): ...@@ -37,15 +33,13 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
spi-max-frequency = <2000000>; spi-max-frequency = <2000000>;
interrupt-parent = <&gpio2>; interrupt-parent = <&gpio2>;
interrupts = <14 0>; interrupts = <14 0>;
ti,enable-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>, ti,enable-gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>,
<&gpio2 5 GPIO_ACTIVE_LOW>; <&gpio2 5 GPIO_ACTIVE_HIGH>;
vin-supply = <&ldo3_reg>; vin-supply = <&ldo3_reg>;
vin-voltage-override = <5000000>;
vdd-io-supply = <&ldo2_reg>; vdd-io-supply = <&ldo2_reg>;
autosuspend-delay = <30000>; autosuspend-delay = <30000>;
irq-status-read-quirk; irq-status-read-quirk;
en2-rf-quirk; en2-rf-quirk;
t5t-rmb-extra-byte-quirk;
clock-frequency = <27120000>; clock-frequency = <27120000>;
status = "okay"; status = "okay";
}; };
......
...@@ -9082,9 +9082,6 @@ F: include/uapi/linux/nfc.h ...@@ -9082,9 +9082,6 @@ F: include/uapi/linux/nfc.h
F: drivers/nfc/ F: drivers/nfc/
F: include/linux/platform_data/nfcmrvl.h F: include/linux/platform_data/nfcmrvl.h
F: include/linux/platform_data/nxp-nci.h F: include/linux/platform_data/nxp-nci.h
F: include/linux/platform_data/pn544.h
F: include/linux/platform_data/st21nfca.h
F: include/linux/platform_data/st-nci.h
F: Documentation/devicetree/bindings/net/nfc/ F: Documentation/devicetree/bindings/net/nfc/
NFS, SUNRPC, AND LOCKD CLIENTS NFS, SUNRPC, AND LOCKD CLIENTS
...@@ -11419,6 +11416,14 @@ F: kernel/time/alarmtimer.c ...@@ -11419,6 +11416,14 @@ F: kernel/time/alarmtimer.c
F: kernel/time/ntp.c F: kernel/time/ntp.c
F: tools/testing/selftests/timers/ F: tools/testing/selftests/timers/
TI TRF7970A NFC DRIVER
M: Mark Greer <mgreer@animalcreek.com>
L: linux-wireless@vger.kernel.org
L: linux-nfc@lists.01.org (moderated for non-subscribers)
S: Supported
F: drivers/nfc/trf7970a.c
F: Documentation/devicetree/bindings/net/nfc/trf7970a.txt
SC1200 WDT DRIVER SC1200 WDT DRIVER
M: Zwane Mwaikambo <zwanem@gmail.com> M: Zwane Mwaikambo <zwanem@gmail.com>
S: Maintained S: Maintained
......
...@@ -7,7 +7,7 @@ menu "Near Field Communication (NFC) devices" ...@@ -7,7 +7,7 @@ menu "Near Field Communication (NFC) devices"
config NFC_TRF7970A config NFC_TRF7970A
tristate "Texas Instruments TRF7970a NFC driver" tristate "Texas Instruments TRF7970a NFC driver"
depends on SPI && NFC_DIGITAL depends on SPI && NFC_DIGITAL && GPIOLIB
help help
This option enables the NFC driver for Texas Instruments' TRF7970a This option enables the NFC driver for Texas Instruments' TRF7970a
device. Such device supports 5 different protocols: ISO14443A, device. Such device supports 5 different protocols: ISO14443A,
......
...@@ -749,11 +749,9 @@ int fdp_nci_probe(struct fdp_i2c_phy *phy, struct nfc_phy_ops *phy_ops, ...@@ -749,11 +749,9 @@ int fdp_nci_probe(struct fdp_i2c_phy *phy, struct nfc_phy_ops *phy_ops,
u32 protocols; u32 protocols;
int r; int r;
info = kzalloc(sizeof(struct fdp_nci_info), GFP_KERNEL); info = devm_kzalloc(dev, sizeof(struct fdp_nci_info), GFP_KERNEL);
if (!info) { if (!info)
r = -ENOMEM; return -ENOMEM;
goto err_info_alloc;
}
info->phy = phy; info->phy = phy;
info->phy_ops = phy_ops; info->phy_ops = phy_ops;
...@@ -775,8 +773,7 @@ int fdp_nci_probe(struct fdp_i2c_phy *phy, struct nfc_phy_ops *phy_ops, ...@@ -775,8 +773,7 @@ int fdp_nci_probe(struct fdp_i2c_phy *phy, struct nfc_phy_ops *phy_ops,
tx_tailroom); tx_tailroom);
if (!ndev) { if (!ndev) {
nfc_err(dev, "Cannot allocate nfc ndev\n"); nfc_err(dev, "Cannot allocate nfc ndev\n");
r = -ENOMEM; return -ENOMEM;
goto err_alloc_ndev;
} }
r = nci_register_device(ndev); r = nci_register_device(ndev);
...@@ -792,9 +789,6 @@ int fdp_nci_probe(struct fdp_i2c_phy *phy, struct nfc_phy_ops *phy_ops, ...@@ -792,9 +789,6 @@ int fdp_nci_probe(struct fdp_i2c_phy *phy, struct nfc_phy_ops *phy_ops,
err_regdev: err_regdev:
nci_free_device(ndev); nci_free_device(ndev);
err_alloc_ndev:
kfree(info);
err_info_alloc:
return r; return r;
} }
EXPORT_SYMBOL(fdp_nci_probe); EXPORT_SYMBOL(fdp_nci_probe);
...@@ -808,7 +802,6 @@ void fdp_nci_remove(struct nci_dev *ndev) ...@@ -808,7 +802,6 @@ void fdp_nci_remove(struct nci_dev *ndev)
nci_unregister_device(ndev); nci_unregister_device(ndev);
nci_free_device(ndev); nci_free_device(ndev);
kfree(info);
} }
EXPORT_SYMBOL(fdp_nci_remove); EXPORT_SYMBOL(fdp_nci_remove);
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#define FDP_I2C_DRIVER_NAME "fdp_nci_i2c" #define FDP_I2C_DRIVER_NAME "fdp_nci_i2c"
#define FDP_DP_POWER_GPIO_NAME "power"
#define FDP_DP_CLOCK_TYPE_NAME "clock-type" #define FDP_DP_CLOCK_TYPE_NAME "clock-type"
#define FDP_DP_CLOCK_FREQ_NAME "clock-freq" #define FDP_DP_CLOCK_FREQ_NAME "clock-freq"
#define FDP_DP_FW_VSC_CFG_NAME "fw-vsc-cfg" #define FDP_DP_FW_VSC_CFG_NAME "fw-vsc-cfg"
...@@ -281,8 +280,14 @@ static void fdp_nci_i2c_read_device_properties(struct device *dev, ...@@ -281,8 +280,14 @@ static void fdp_nci_i2c_read_device_properties(struct device *dev,
*clock_type, *clock_freq, *fw_vsc_cfg != NULL ? "yes" : "no"); *clock_type, *clock_freq, *fw_vsc_cfg != NULL ? "yes" : "no");
} }
static int fdp_nci_i2c_probe(struct i2c_client *client, static const struct acpi_gpio_params power_gpios = { 0, 0, false };
const struct i2c_device_id *id)
static const struct acpi_gpio_mapping acpi_fdp_gpios[] = {
{ "power-gpios", &power_gpios, 1 },
{},
};
static int fdp_nci_i2c_probe(struct i2c_client *client)
{ {
struct fdp_i2c_phy *phy; struct fdp_i2c_phy *phy;
struct device *dev = &client->dev; struct device *dev = &client->dev;
...@@ -304,8 +309,7 @@ static int fdp_nci_i2c_probe(struct i2c_client *client, ...@@ -304,8 +309,7 @@ static int fdp_nci_i2c_probe(struct i2c_client *client,
return -ENODEV; return -ENODEV;
} }
phy = devm_kzalloc(dev, sizeof(struct fdp_i2c_phy), phy = devm_kzalloc(dev, sizeof(struct fdp_i2c_phy), GFP_KERNEL);
GFP_KERNEL);
if (!phy) if (!phy)
return -ENOMEM; return -ENOMEM;
...@@ -313,7 +317,8 @@ static int fdp_nci_i2c_probe(struct i2c_client *client, ...@@ -313,7 +317,8 @@ static int fdp_nci_i2c_probe(struct i2c_client *client,
phy->next_read_size = FDP_NCI_I2C_MIN_PAYLOAD; phy->next_read_size = FDP_NCI_I2C_MIN_PAYLOAD;
i2c_set_clientdata(client, phy); i2c_set_clientdata(client, phy);
r = request_threaded_irq(client->irq, NULL, fdp_nci_i2c_irq_thread_fn, r = devm_request_threaded_irq(dev, client->irq,
NULL, fdp_nci_i2c_irq_thread_fn,
IRQF_TRIGGER_RISING | IRQF_ONESHOT, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
FDP_I2C_DRIVER_NAME, phy); FDP_I2C_DRIVER_NAME, phy);
...@@ -322,10 +327,12 @@ static int fdp_nci_i2c_probe(struct i2c_client *client, ...@@ -322,10 +327,12 @@ static int fdp_nci_i2c_probe(struct i2c_client *client,
return r; return r;
} }
/* Requesting the power gpio */ r = devm_acpi_dev_add_driver_gpios(dev, acpi_fdp_gpios);
phy->power_gpio = devm_gpiod_get(dev, FDP_DP_POWER_GPIO_NAME, if (r)
GPIOD_OUT_LOW); dev_dbg(dev, "Unable to add GPIO mapping table\n");
/* Requesting the power gpio */
phy->power_gpio = devm_gpiod_get(dev, "power", GPIOD_OUT_LOW);
if (IS_ERR(phy->power_gpio)) { if (IS_ERR(phy->power_gpio)) {
nfc_err(dev, "Power GPIO request failed\n"); nfc_err(dev, "Power GPIO request failed\n");
return PTR_ERR(phy->power_gpio); return PTR_ERR(phy->power_gpio);
...@@ -360,12 +367,6 @@ static int fdp_nci_i2c_remove(struct i2c_client *client) ...@@ -360,12 +367,6 @@ static int fdp_nci_i2c_remove(struct i2c_client *client)
return 0; return 0;
} }
static struct i2c_device_id fdp_nci_i2c_id_table[] = {
{"int339a", 0},
{}
};
MODULE_DEVICE_TABLE(i2c, fdp_nci_i2c_id_table);
static const struct acpi_device_id fdp_nci_i2c_acpi_match[] = { static const struct acpi_device_id fdp_nci_i2c_acpi_match[] = {
{"INT339A", 0}, {"INT339A", 0},
{} {}
...@@ -377,8 +378,7 @@ static struct i2c_driver fdp_nci_i2c_driver = { ...@@ -377,8 +378,7 @@ static struct i2c_driver fdp_nci_i2c_driver = {
.name = FDP_I2C_DRIVER_NAME, .name = FDP_I2C_DRIVER_NAME,
.acpi_match_table = ACPI_PTR(fdp_nci_i2c_acpi_match), .acpi_match_table = ACPI_PTR(fdp_nci_i2c_acpi_match),
}, },
.id_table = fdp_nci_i2c_id_table, .probe_new = fdp_nci_i2c_probe,
.probe = fdp_nci_i2c_probe,
.remove = fdp_nci_i2c_remove, .remove = fdp_nci_i2c_remove,
}; };
module_i2c_driver(fdp_nci_i2c_driver); module_i2c_driver(fdp_nci_i2c_driver);
......
...@@ -457,7 +457,7 @@ int nfcmrvl_fw_dnld_init(struct nfcmrvl_private *priv) ...@@ -457,7 +457,7 @@ int nfcmrvl_fw_dnld_init(struct nfcmrvl_private *priv)
INIT_WORK(&priv->fw_dnld.rx_work, fw_dnld_rx_work); INIT_WORK(&priv->fw_dnld.rx_work, fw_dnld_rx_work);
snprintf(name, sizeof(name), "%s_nfcmrvl_fw_dnld_rx_wq", snprintf(name, sizeof(name), "%s_nfcmrvl_fw_dnld_rx_wq",
dev_name(priv->dev)); dev_name(&priv->ndev->nfc_dev->dev));
priv->fw_dnld.rx_wq = create_singlethread_workqueue(name); priv->fw_dnld.rx_wq = create_singlethread_workqueue(name);
if (!priv->fw_dnld.rx_wq) if (!priv->fw_dnld.rx_wq)
return -ENOMEM; return -ENOMEM;
...@@ -494,6 +494,7 @@ int nfcmrvl_fw_dnld_start(struct nci_dev *ndev, const char *firmware_name) ...@@ -494,6 +494,7 @@ int nfcmrvl_fw_dnld_start(struct nci_dev *ndev, const char *firmware_name)
{ {
struct nfcmrvl_private *priv = nci_get_drvdata(ndev); struct nfcmrvl_private *priv = nci_get_drvdata(ndev);
struct nfcmrvl_fw_dnld *fw_dnld = &priv->fw_dnld; struct nfcmrvl_fw_dnld *fw_dnld = &priv->fw_dnld;
int res;
if (!priv->support_fw_dnld) if (!priv->support_fw_dnld)
return -ENOTSUPP; return -ENOTSUPP;
...@@ -509,7 +510,9 @@ int nfcmrvl_fw_dnld_start(struct nci_dev *ndev, const char *firmware_name) ...@@ -509,7 +510,9 @@ int nfcmrvl_fw_dnld_start(struct nci_dev *ndev, const char *firmware_name)
*/ */
/* Retrieve FW binary */ /* Retrieve FW binary */
if (request_firmware(&fw_dnld->fw, firmware_name, priv->dev) < 0) { res = request_firmware(&fw_dnld->fw, firmware_name,
&ndev->nfc_dev->dev);
if (res < 0) {
nfc_err(priv->dev, "failed to retrieve FW %s", firmware_name); nfc_err(priv->dev, "failed to retrieve FW %s", firmware_name);
return -ENOENT; return -ENOENT;
} }
......
...@@ -123,14 +123,15 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(enum nfcmrvl_phy phy, ...@@ -123,14 +123,15 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(enum nfcmrvl_phy phy,
memcpy(&priv->config, pdata, sizeof(*pdata)); memcpy(&priv->config, pdata, sizeof(*pdata));
if (priv->config.reset_n_io) { if (gpio_is_valid(priv->config.reset_n_io)) {
rc = devm_gpio_request_one(dev, rc = gpio_request_one(priv->config.reset_n_io,
priv->config.reset_n_io,
GPIOF_OUT_INIT_LOW, GPIOF_OUT_INIT_LOW,
"nfcmrvl_reset_n"); "nfcmrvl_reset_n");
if (rc < 0) if (rc < 0) {
priv->config.reset_n_io = -EINVAL;
nfc_err(dev, "failed to request reset_n io\n"); nfc_err(dev, "failed to request reset_n io\n");
} }
}
if (phy == NFCMRVL_PHY_SPI) { if (phy == NFCMRVL_PHY_SPI) {
headroom = NCI_SPI_HDR_LEN; headroom = NCI_SPI_HDR_LEN;
...@@ -154,7 +155,13 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(enum nfcmrvl_phy phy, ...@@ -154,7 +155,13 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(enum nfcmrvl_phy phy,
if (!priv->ndev) { if (!priv->ndev) {
nfc_err(dev, "nci_allocate_device failed\n"); nfc_err(dev, "nci_allocate_device failed\n");
rc = -ENOMEM; rc = -ENOMEM;
goto error; goto error_free_gpio;
}
rc = nfcmrvl_fw_dnld_init(priv);
if (rc) {
nfc_err(dev, "failed to initialize FW download %d\n", rc);
goto error_free_dev;
} }
nci_set_drvdata(priv->ndev, priv); nci_set_drvdata(priv->ndev, priv);
...@@ -162,24 +169,22 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(enum nfcmrvl_phy phy, ...@@ -162,24 +169,22 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(enum nfcmrvl_phy phy,
rc = nci_register_device(priv->ndev); rc = nci_register_device(priv->ndev);
if (rc) { if (rc) {
nfc_err(dev, "nci_register_device failed %d\n", rc); nfc_err(dev, "nci_register_device failed %d\n", rc);
goto error_free_dev; goto error_fw_dnld_deinit;
} }
/* Ensure that controller is powered off */ /* Ensure that controller is powered off */
nfcmrvl_chip_halt(priv); nfcmrvl_chip_halt(priv);
rc = nfcmrvl_fw_dnld_init(priv);
if (rc) {
nfc_err(dev, "failed to initialize FW download %d\n", rc);
goto error_free_dev;
}
nfc_info(dev, "registered with nci successfully\n"); nfc_info(dev, "registered with nci successfully\n");
return priv; return priv;
error_fw_dnld_deinit:
nfcmrvl_fw_dnld_deinit(priv);
error_free_dev: error_free_dev:
nci_free_device(priv->ndev); nci_free_device(priv->ndev);
error: error_free_gpio:
if (gpio_is_valid(priv->config.reset_n_io))
gpio_free(priv->config.reset_n_io);
kfree(priv); kfree(priv);
return ERR_PTR(rc); return ERR_PTR(rc);
} }
...@@ -194,8 +199,8 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv) ...@@ -194,8 +199,8 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv)
nfcmrvl_fw_dnld_deinit(priv); nfcmrvl_fw_dnld_deinit(priv);
if (priv->config.reset_n_io) if (gpio_is_valid(priv->config.reset_n_io))
devm_gpio_free(priv->dev, priv->config.reset_n_io); gpio_free(priv->config.reset_n_io);
nci_unregister_device(ndev); nci_unregister_device(ndev);
nci_free_device(ndev); nci_free_device(ndev);
...@@ -262,7 +267,6 @@ int nfcmrvl_parse_dt(struct device_node *node, ...@@ -262,7 +267,6 @@ int nfcmrvl_parse_dt(struct device_node *node,
reset_n_io = of_get_named_gpio(node, "reset-n-io", 0); reset_n_io = of_get_named_gpio(node, "reset-n-io", 0);
if (reset_n_io < 0) { if (reset_n_io < 0) {
pr_info("no reset-n-io config\n"); pr_info("no reset-n-io config\n");
reset_n_io = 0;
} else if (!gpio_is_valid(reset_n_io)) { } else if (!gpio_is_valid(reset_n_io)) {
pr_err("invalid reset-n-io GPIO\n"); pr_err("invalid reset-n-io GPIO\n");
return reset_n_io; return reset_n_io;
......
...@@ -84,6 +84,7 @@ static int nfcmrvl_uart_parse_dt(struct device_node *node, ...@@ -84,6 +84,7 @@ static int nfcmrvl_uart_parse_dt(struct device_node *node,
ret = nfcmrvl_parse_dt(matched_node, pdata); ret = nfcmrvl_parse_dt(matched_node, pdata);
if (ret < 0) { if (ret < 0) {
pr_err("Failed to get generic entries\n"); pr_err("Failed to get generic entries\n");
of_node_put(matched_node);
return ret; return ret;
} }
...@@ -97,6 +98,8 @@ static int nfcmrvl_uart_parse_dt(struct device_node *node, ...@@ -97,6 +98,8 @@ static int nfcmrvl_uart_parse_dt(struct device_node *node,
else else
pdata->break_control = 0; pdata->break_control = 0;
of_node_put(matched_node);
return 0; return 0;
} }
...@@ -109,6 +112,7 @@ static int nfcmrvl_nci_uart_open(struct nci_uart *nu) ...@@ -109,6 +112,7 @@ static int nfcmrvl_nci_uart_open(struct nci_uart *nu)
struct nfcmrvl_private *priv; struct nfcmrvl_private *priv;
struct nfcmrvl_platform_data *pdata = NULL; struct nfcmrvl_platform_data *pdata = NULL;
struct nfcmrvl_platform_data config; struct nfcmrvl_platform_data config;
struct device *dev = nu->tty->dev;
/* /*
* Platform data cannot be used here since usually it is already used * Platform data cannot be used here since usually it is already used
...@@ -116,9 +120,8 @@ static int nfcmrvl_nci_uart_open(struct nci_uart *nu) ...@@ -116,9 +120,8 @@ static int nfcmrvl_nci_uart_open(struct nci_uart *nu)
* and check if DT entries were added. * and check if DT entries were added.
*/ */
if (nu->tty->dev->parent && nu->tty->dev->parent->of_node) if (dev && dev->parent && dev->parent->of_node)
if (nfcmrvl_uart_parse_dt(nu->tty->dev->parent->of_node, if (nfcmrvl_uart_parse_dt(dev->parent->of_node, &config) == 0)
&config) == 0)
pdata = &config; pdata = &config;
if (!pdata) { if (!pdata) {
...@@ -131,7 +134,7 @@ static int nfcmrvl_nci_uart_open(struct nci_uart *nu) ...@@ -131,7 +134,7 @@ static int nfcmrvl_nci_uart_open(struct nci_uart *nu)
} }
priv = nfcmrvl_nci_register_dev(NFCMRVL_PHY_UART, nu, &uart_ops, priv = nfcmrvl_nci_register_dev(NFCMRVL_PHY_UART, nu, &uart_ops,
nu->tty->dev, pdata); dev, pdata);
if (IS_ERR(priv)) if (IS_ERR(priv))
return PTR_ERR(priv); return PTR_ERR(priv);
......
...@@ -341,15 +341,13 @@ static int nfcmrvl_probe(struct usb_interface *intf, ...@@ -341,15 +341,13 @@ static int nfcmrvl_probe(struct usb_interface *intf,
init_usb_anchor(&drv_data->deferred); init_usb_anchor(&drv_data->deferred);
priv = nfcmrvl_nci_register_dev(NFCMRVL_PHY_USB, drv_data, &usb_ops, priv = nfcmrvl_nci_register_dev(NFCMRVL_PHY_USB, drv_data, &usb_ops,
&drv_data->udev->dev, &config); &intf->dev, &config);
if (IS_ERR(priv)) if (IS_ERR(priv))
return PTR_ERR(priv); return PTR_ERR(priv);
drv_data->priv = priv; drv_data->priv = priv;
drv_data->priv->support_fw_dnld = false; drv_data->priv->support_fw_dnld = false;
priv->dev = &drv_data->udev->dev;
usb_set_intfdata(intf, drv_data); usb_set_intfdata(intf, drv_data);
return 0; return 0;
......
...@@ -482,7 +482,9 @@ static int __init nfcsim_init(void) ...@@ -482,7 +482,9 @@ static int __init nfcsim_init(void)
exit_err: exit_err:
pr_err("Failed to initialize nfcsim driver (%d)\n", rc); pr_err("Failed to initialize nfcsim driver (%d)\n", rc);
if (link0)
nfcsim_link_free(link0); nfcsim_link_free(link0);
if (link1)
nfcsim_link_free(link1); nfcsim_link_free(link1);
return rc; return rc;
......
...@@ -904,7 +904,7 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, ...@@ -904,7 +904,7 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
phy->i2c_dev = client; phy->i2c_dev = client;
i2c_set_clientdata(client, phy); i2c_set_clientdata(client, phy);
r = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), acpi_pn544_gpios); r = devm_acpi_dev_add_driver_gpios(dev, acpi_pn544_gpios);
if (r) if (r)
dev_dbg(dev, "Unable to add GPIO mapping table\n"); dev_dbg(dev, "Unable to add GPIO mapping table\n");
...@@ -958,7 +958,6 @@ static int pn544_hci_i2c_remove(struct i2c_client *client) ...@@ -958,7 +958,6 @@ static int pn544_hci_i2c_remove(struct i2c_client *client)
if (phy->powered) if (phy->powered)
pn544_hci_i2c_disable(phy); pn544_hci_i2c_disable(phy);
acpi_dev_remove_driver_gpios(ACPI_COMPANION(&client->dev));
return 0; return 0;
} }
......
...@@ -19,15 +19,12 @@ ...@@ -19,15 +19,12 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/of_irq.h>
#include <linux/of_gpio.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/nfc.h> #include <linux/nfc.h>
#include <linux/platform_data/st-nci.h> #include <linux/of.h>
#include "st-nci.h" #include "st-nci.h"
...@@ -40,18 +37,16 @@ ...@@ -40,18 +37,16 @@
#define ST_NCI_I2C_MIN_SIZE 4 /* PCB(1) + NCI Packet header(3) */ #define ST_NCI_I2C_MIN_SIZE 4 /* PCB(1) + NCI Packet header(3) */
#define ST_NCI_I2C_MAX_SIZE 250 /* req 4.2.1 */ #define ST_NCI_I2C_MAX_SIZE 250 /* req 4.2.1 */
#define ST_NCI_DRIVER_NAME "st_nci"
#define ST_NCI_I2C_DRIVER_NAME "st_nci_i2c" #define ST_NCI_I2C_DRIVER_NAME "st_nci_i2c"
#define ST_NCI_GPIO_NAME_RESET "reset"
struct st_nci_i2c_phy { struct st_nci_i2c_phy {
struct i2c_client *i2c_dev; struct i2c_client *i2c_dev;
struct llt_ndlc *ndlc; struct llt_ndlc *ndlc;
bool irq_active; bool irq_active;
unsigned int gpio_reset; struct gpio_desc *gpiod_reset;
unsigned int irq_polarity;
struct st_nci_se_status se_status; struct st_nci_se_status se_status;
}; };
...@@ -60,9 +55,9 @@ static int st_nci_i2c_enable(void *phy_id) ...@@ -60,9 +55,9 @@ static int st_nci_i2c_enable(void *phy_id)
{ {
struct st_nci_i2c_phy *phy = phy_id; struct st_nci_i2c_phy *phy = phy_id;
gpio_set_value(phy->gpio_reset, 0); gpiod_set_value(phy->gpiod_reset, 0);
usleep_range(10000, 15000); usleep_range(10000, 15000);
gpio_set_value(phy->gpio_reset, 1); gpiod_set_value(phy->gpiod_reset, 1);
usleep_range(80000, 85000); usleep_range(80000, 85000);
if (phy->ndlc->powered == 0 && phy->irq_active == 0) { if (phy->ndlc->powered == 0 && phy->irq_active == 0) {
...@@ -208,114 +203,18 @@ static struct nfc_phy_ops i2c_phy_ops = { ...@@ -208,114 +203,18 @@ static struct nfc_phy_ops i2c_phy_ops = {
.disable = st_nci_i2c_disable, .disable = st_nci_i2c_disable,
}; };
static int st_nci_i2c_acpi_request_resources(struct i2c_client *client) static const struct acpi_gpio_params reset_gpios = { 1, 0, false };
{
struct st_nci_i2c_phy *phy = i2c_get_clientdata(client);
struct gpio_desc *gpiod_reset;
struct device *dev = &client->dev;
u8 tmp;
/* Get RESET GPIO from ACPI */
gpiod_reset = devm_gpiod_get_index(dev, ST_NCI_GPIO_NAME_RESET, 1,
GPIOD_OUT_HIGH);
if (IS_ERR(gpiod_reset)) {
nfc_err(dev, "Unable to get RESET GPIO\n");
return -ENODEV;
}
phy->gpio_reset = desc_to_gpio(gpiod_reset);
phy->irq_polarity = irq_get_trigger_type(client->irq);
phy->se_status.is_ese_present = false;
phy->se_status.is_uicc_present = false;
if (device_property_present(dev, "ese-present")) {
device_property_read_u8(dev, "ese-present", &tmp);
phy->se_status.is_ese_present = tmp;
}
if (device_property_present(dev, "uicc-present")) {
device_property_read_u8(dev, "uicc-present", &tmp);
phy->se_status.is_uicc_present = tmp;
}
return 0;
}
static int st_nci_i2c_of_request_resources(struct i2c_client *client)
{
struct st_nci_i2c_phy *phy = i2c_get_clientdata(client);
struct device_node *pp;
int gpio;
int r;
pp = client->dev.of_node;
if (!pp)
return -ENODEV;
/* Get GPIO from device tree */
gpio = of_get_named_gpio(pp, "reset-gpios", 0);
if (gpio < 0) {
nfc_err(&client->dev,
"Failed to retrieve reset-gpios from device tree\n");
return gpio;
}
/* GPIO request and configuration */
r = devm_gpio_request_one(&client->dev, gpio,
GPIOF_OUT_INIT_HIGH, ST_NCI_GPIO_NAME_RESET);
if (r) {
nfc_err(&client->dev, "Failed to request reset pin\n");
return r;
}
phy->gpio_reset = gpio;
phy->irq_polarity = irq_get_trigger_type(client->irq);
phy->se_status.is_ese_present = static const struct acpi_gpio_mapping acpi_st_nci_gpios[] = {
of_property_read_bool(pp, "ese-present"); { "reset-gpios", &reset_gpios, 1 },
phy->se_status.is_uicc_present = {},
of_property_read_bool(pp, "uicc-present"); };
return 0;
}
static int st_nci_i2c_request_resources(struct i2c_client *client)
{
struct st_nci_nfc_platform_data *pdata;
struct st_nci_i2c_phy *phy = i2c_get_clientdata(client);
int r;
pdata = client->dev.platform_data;
if (pdata == NULL) {
nfc_err(&client->dev, "No platform data\n");
return -EINVAL;
}
/* store for later use */
phy->gpio_reset = pdata->gpio_reset;
phy->irq_polarity = pdata->irq_polarity;
r = devm_gpio_request_one(&client->dev,
phy->gpio_reset, GPIOF_OUT_INIT_HIGH,
ST_NCI_GPIO_NAME_RESET);
if (r) {
pr_err("%s : reset gpio_request failed\n", __FILE__);
return r;
}
phy->se_status.is_ese_present = pdata->is_ese_present;
phy->se_status.is_uicc_present = pdata->is_uicc_present;
return 0;
}
static int st_nci_i2c_probe(struct i2c_client *client, static int st_nci_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct device *dev = &client->dev;
struct st_nci_i2c_phy *phy; struct st_nci_i2c_phy *phy;
struct st_nci_nfc_platform_data *pdata;
int r; int r;
dev_dbg(&client->dev, "%s\n", __func__); dev_dbg(&client->dev, "%s\n", __func__);
...@@ -326,8 +225,7 @@ static int st_nci_i2c_probe(struct i2c_client *client, ...@@ -326,8 +225,7 @@ static int st_nci_i2c_probe(struct i2c_client *client,
return -ENODEV; return -ENODEV;
} }
phy = devm_kzalloc(&client->dev, sizeof(struct st_nci_i2c_phy), phy = devm_kzalloc(dev, sizeof(struct st_nci_i2c_phy), GFP_KERNEL);
GFP_KERNEL);
if (!phy) if (!phy)
return -ENOMEM; return -ENOMEM;
...@@ -335,32 +233,22 @@ static int st_nci_i2c_probe(struct i2c_client *client, ...@@ -335,32 +233,22 @@ static int st_nci_i2c_probe(struct i2c_client *client,
i2c_set_clientdata(client, phy); i2c_set_clientdata(client, phy);
pdata = client->dev.platform_data; r = devm_acpi_dev_add_driver_gpios(dev, acpi_st_nci_gpios);
if (!pdata && client->dev.of_node) { if (r)
r = st_nci_i2c_of_request_resources(client); dev_dbg(dev, "Unable to add GPIO mapping table\n");
if (r) {
nfc_err(&client->dev, "No platform data\n"); /* Get RESET GPIO */
return r; phy->gpiod_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
} if (IS_ERR(phy->gpiod_reset)) {
} else if (pdata) { nfc_err(dev, "Unable to get RESET GPIO\n");
r = st_nci_i2c_request_resources(client);
if (r) {
nfc_err(&client->dev,
"Cannot get platform resources\n");
return r;
}
} else if (ACPI_HANDLE(&client->dev)) {
r = st_nci_i2c_acpi_request_resources(client);
if (r) {
nfc_err(&client->dev, "Cannot get ACPI data\n");
return r;
}
} else {
nfc_err(&client->dev,
"st_nci platform resources not available\n");
return -ENODEV; return -ENODEV;
} }
phy->se_status.is_ese_present =
device_property_read_bool(dev, "ese-present");
phy->se_status.is_uicc_present =
device_property_read_bool(dev, "uicc-present");
r = ndlc_probe(phy, &i2c_phy_ops, &client->dev, r = ndlc_probe(phy, &i2c_phy_ops, &client->dev,
ST_NCI_FRAME_HEADROOM, ST_NCI_FRAME_TAILROOM, ST_NCI_FRAME_HEADROOM, ST_NCI_FRAME_TAILROOM,
&phy->ndlc, &phy->se_status); &phy->ndlc, &phy->se_status);
...@@ -372,7 +260,7 @@ static int st_nci_i2c_probe(struct i2c_client *client, ...@@ -372,7 +260,7 @@ static int st_nci_i2c_probe(struct i2c_client *client,
phy->irq_active = true; phy->irq_active = true;
r = devm_request_threaded_irq(&client->dev, client->irq, NULL, r = devm_request_threaded_irq(&client->dev, client->irq, NULL,
st_nci_irq_thread_fn, st_nci_irq_thread_fn,
phy->irq_polarity | IRQF_ONESHOT, IRQF_ONESHOT,
ST_NCI_DRIVER_NAME, phy); ST_NCI_DRIVER_NAME, phy);
if (r < 0) if (r < 0)
nfc_err(&client->dev, "Unable to register IRQ handler\n"); nfc_err(&client->dev, "Unable to register IRQ handler\n");
......
...@@ -19,16 +19,13 @@ ...@@ -19,16 +19,13 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/of_irq.h>
#include <linux/of_gpio.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/nfc.h> #include <linux/nfc.h>
#include <linux/of.h>
#include <net/nfc/nci.h> #include <net/nfc/nci.h>
#include <linux/platform_data/st-nci.h>
#include "st-nci.h" #include "st-nci.h"
...@@ -41,18 +38,16 @@ ...@@ -41,18 +38,16 @@
#define ST_NCI_SPI_MIN_SIZE 4 /* PCB(1) + NCI Packet header(3) */ #define ST_NCI_SPI_MIN_SIZE 4 /* PCB(1) + NCI Packet header(3) */
#define ST_NCI_SPI_MAX_SIZE 250 /* req 4.2.1 */ #define ST_NCI_SPI_MAX_SIZE 250 /* req 4.2.1 */
#define ST_NCI_DRIVER_NAME "st_nci"
#define ST_NCI_SPI_DRIVER_NAME "st_nci_spi" #define ST_NCI_SPI_DRIVER_NAME "st_nci_spi"
#define ST_NCI_GPIO_NAME_RESET "reset"
struct st_nci_spi_phy { struct st_nci_spi_phy {
struct spi_device *spi_dev; struct spi_device *spi_dev;
struct llt_ndlc *ndlc; struct llt_ndlc *ndlc;
bool irq_active; bool irq_active;
unsigned int gpio_reset; struct gpio_desc *gpiod_reset;
unsigned int irq_polarity;
struct st_nci_se_status se_status; struct st_nci_se_status se_status;
}; };
...@@ -61,9 +56,9 @@ static int st_nci_spi_enable(void *phy_id) ...@@ -61,9 +56,9 @@ static int st_nci_spi_enable(void *phy_id)
{ {
struct st_nci_spi_phy *phy = phy_id; struct st_nci_spi_phy *phy = phy_id;
gpio_set_value(phy->gpio_reset, 0); gpiod_set_value(phy->gpiod_reset, 0);
usleep_range(10000, 15000); usleep_range(10000, 15000);
gpio_set_value(phy->gpio_reset, 1); gpiod_set_value(phy->gpiod_reset, 1);
usleep_range(80000, 85000); usleep_range(80000, 85000);
if (phy->ndlc->powered == 0 && phy->irq_active == 0) { if (phy->ndlc->powered == 0 && phy->irq_active == 0) {
...@@ -223,113 +218,16 @@ static struct nfc_phy_ops spi_phy_ops = { ...@@ -223,113 +218,16 @@ static struct nfc_phy_ops spi_phy_ops = {
.disable = st_nci_spi_disable, .disable = st_nci_spi_disable,
}; };
static int st_nci_spi_acpi_request_resources(struct spi_device *spi_dev) static const struct acpi_gpio_params reset_gpios = { 1, 0, false };
{
struct st_nci_spi_phy *phy = spi_get_drvdata(spi_dev);
struct gpio_desc *gpiod_reset;
struct device *dev = &spi_dev->dev;
u8 tmp;
/* Get RESET GPIO from ACPI */
gpiod_reset = devm_gpiod_get_index(dev, ST_NCI_GPIO_NAME_RESET, 1,
GPIOD_OUT_HIGH);
if (IS_ERR(gpiod_reset)) {
nfc_err(dev, "Unable to get RESET GPIO\n");
return -ENODEV;
}
phy->gpio_reset = desc_to_gpio(gpiod_reset);
phy->irq_polarity = irq_get_trigger_type(spi_dev->irq);
phy->se_status.is_ese_present = false;
phy->se_status.is_uicc_present = false;
if (device_property_present(dev, "ese-present")) {
device_property_read_u8(dev, "ese-present", &tmp);
tmp = phy->se_status.is_ese_present;
}
if (device_property_present(dev, "uicc-present")) {
device_property_read_u8(dev, "uicc-present", &tmp);
tmp = phy->se_status.is_uicc_present;
}
return 0;
}
static int st_nci_spi_of_request_resources(struct spi_device *dev)
{
struct st_nci_spi_phy *phy = spi_get_drvdata(dev);
struct device_node *pp;
int gpio;
int r;
pp = dev->dev.of_node;
if (!pp)
return -ENODEV;
/* Get GPIO from device tree */ static const struct acpi_gpio_mapping acpi_st_nci_gpios[] = {
gpio = of_get_named_gpio(pp, "reset-gpios", 0); { "reset-gpios", &reset_gpios, 1 },
if (gpio < 0) { {},
nfc_err(&dev->dev, };
"Failed to retrieve reset-gpios from device tree\n");
return gpio;
}
/* GPIO request and configuration */
r = devm_gpio_request_one(&dev->dev, gpio,
GPIOF_OUT_INIT_HIGH, ST_NCI_GPIO_NAME_RESET);
if (r) {
nfc_err(&dev->dev, "Failed to request reset pin\n");
return r;
}
phy->gpio_reset = gpio;
phy->irq_polarity = irq_get_trigger_type(dev->irq);
phy->se_status.is_ese_present =
of_property_read_bool(pp, "ese-present");
phy->se_status.is_uicc_present =
of_property_read_bool(pp, "uicc-present");
return 0;
}
static int st_nci_spi_request_resources(struct spi_device *dev)
{
struct st_nci_nfc_platform_data *pdata;
struct st_nci_spi_phy *phy = spi_get_drvdata(dev);
int r;
pdata = dev->dev.platform_data;
if (pdata == NULL) {
nfc_err(&dev->dev, "No platform data\n");
return -EINVAL;
}
/* store for later use */
phy->gpio_reset = pdata->gpio_reset;
phy->irq_polarity = pdata->irq_polarity;
r = devm_gpio_request_one(&dev->dev,
phy->gpio_reset, GPIOF_OUT_INIT_HIGH,
ST_NCI_GPIO_NAME_RESET);
if (r) {
pr_err("%s : reset gpio_request failed\n", __FILE__);
return r;
}
phy->se_status.is_ese_present = pdata->is_ese_present;
phy->se_status.is_uicc_present = pdata->is_uicc_present;
return 0;
}
static int st_nci_spi_probe(struct spi_device *dev) static int st_nci_spi_probe(struct spi_device *dev)
{ {
struct st_nci_spi_phy *phy; struct st_nci_spi_phy *phy;
struct st_nci_nfc_platform_data *pdata;
int r; int r;
dev_dbg(&dev->dev, "%s\n", __func__); dev_dbg(&dev->dev, "%s\n", __func__);
...@@ -351,32 +249,22 @@ static int st_nci_spi_probe(struct spi_device *dev) ...@@ -351,32 +249,22 @@ static int st_nci_spi_probe(struct spi_device *dev)
spi_set_drvdata(dev, phy); spi_set_drvdata(dev, phy);
pdata = dev->dev.platform_data; r = devm_acpi_dev_add_driver_gpios(&dev->dev, acpi_st_nci_gpios);
if (!pdata && dev->dev.of_node) { if (r)
r = st_nci_spi_of_request_resources(dev); dev_dbg(&dev->dev, "Unable to add GPIO mapping table\n");
if (r) {
nfc_err(&dev->dev, "No platform data\n"); /* Get RESET GPIO */
return r; phy->gpiod_reset = devm_gpiod_get(&dev->dev, "reset", GPIOD_OUT_HIGH);
} if (IS_ERR(phy->gpiod_reset)) {
} else if (pdata) { nfc_err(&dev->dev, "Unable to get RESET GPIO\n");
r = st_nci_spi_request_resources(dev); return PTR_ERR(phy->gpiod_reset);
if (r) {
nfc_err(&dev->dev,
"Cannot get platform resources\n");
return r;
}
} else if (ACPI_HANDLE(&dev->dev)) {
r = st_nci_spi_acpi_request_resources(dev);
if (r) {
nfc_err(&dev->dev, "Cannot get ACPI data\n");
return r;
}
} else {
nfc_err(&dev->dev,
"st_nci platform resources not available\n");
return -ENODEV;
} }
phy->se_status.is_ese_present =
device_property_read_bool(&dev->dev, "ese-present");
phy->se_status.is_uicc_present =
device_property_read_bool(&dev->dev, "uicc-present");
r = ndlc_probe(phy, &spi_phy_ops, &dev->dev, r = ndlc_probe(phy, &spi_phy_ops, &dev->dev,
ST_NCI_FRAME_HEADROOM, ST_NCI_FRAME_TAILROOM, ST_NCI_FRAME_HEADROOM, ST_NCI_FRAME_TAILROOM,
&phy->ndlc, &phy->se_status); &phy->ndlc, &phy->se_status);
...@@ -388,7 +276,7 @@ static int st_nci_spi_probe(struct spi_device *dev) ...@@ -388,7 +276,7 @@ static int st_nci_spi_probe(struct spi_device *dev)
phy->irq_active = true; phy->irq_active = true;
r = devm_request_threaded_irq(&dev->dev, dev->irq, NULL, r = devm_request_threaded_irq(&dev->dev, dev->irq, NULL,
st_nci_irq_thread_fn, st_nci_irq_thread_fn,
phy->irq_polarity | IRQF_ONESHOT, IRQF_ONESHOT,
ST_NCI_SPI_DRIVER_NAME, phy); ST_NCI_SPI_DRIVER_NAME, phy);
if (r < 0) if (r < 0)
nfc_err(&dev->dev, "Unable to register IRQ handler\n"); nfc_err(&dev->dev, "Unable to register IRQ handler\n");
......
...@@ -61,8 +61,6 @@ ...@@ -61,8 +61,6 @@
#define ST21NFCA_HCI_DRIVER_NAME "st21nfca_hci" #define ST21NFCA_HCI_DRIVER_NAME "st21nfca_hci"
#define ST21NFCA_HCI_I2C_DRIVER_NAME "st21nfca_hci_i2c" #define ST21NFCA_HCI_I2C_DRIVER_NAME "st21nfca_hci_i2c"
#define ST21NFCA_GPIO_NAME_EN "enable"
struct st21nfca_i2c_phy { struct st21nfca_i2c_phy {
struct i2c_client *i2c_dev; struct i2c_client *i2c_dev;
struct nfc_hci_dev *hdev; struct nfc_hci_dev *hdev;
...@@ -501,41 +499,17 @@ static struct nfc_phy_ops i2c_phy_ops = { ...@@ -501,41 +499,17 @@ static struct nfc_phy_ops i2c_phy_ops = {
.disable = st21nfca_hci_i2c_disable, .disable = st21nfca_hci_i2c_disable,
}; };
static int st21nfca_hci_i2c_acpi_request_resources(struct i2c_client *client) static const struct acpi_gpio_params enable_gpios = { 1, 0, false };
{
struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client);
struct device *dev = &client->dev;
/* Get EN GPIO from ACPI */
phy->gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 1,
GPIOD_OUT_LOW);
if (IS_ERR(phy->gpiod_ena)) {
nfc_err(dev, "Unable to get ENABLE GPIO\n");
return PTR_ERR(phy->gpiod_ena);
}
return 0;
}
static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client)
{
struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client);
struct device *dev = &client->dev;
/* Get GPIO from device tree */
phy->gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 0,
GPIOD_OUT_HIGH);
if (IS_ERR(phy->gpiod_ena)) {
nfc_err(dev, "Failed to request enable pin\n");
return PTR_ERR(phy->gpiod_ena);
}
return 0; static const struct acpi_gpio_mapping acpi_st21nfca_gpios[] = {
} { "enable-gpios", &enable_gpios, 1 },
{},
};
static int st21nfca_hci_i2c_probe(struct i2c_client *client, static int st21nfca_hci_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct device *dev = &client->dev;
struct st21nfca_i2c_phy *phy; struct st21nfca_i2c_phy *phy;
int r; int r;
...@@ -562,21 +536,15 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, ...@@ -562,21 +536,15 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client,
mutex_init(&phy->phy_lock); mutex_init(&phy->phy_lock);
i2c_set_clientdata(client, phy); i2c_set_clientdata(client, phy);
if (client->dev.of_node) { r = devm_acpi_dev_add_driver_gpios(dev, acpi_st21nfca_gpios);
r = st21nfca_hci_i2c_of_request_resources(client); if (r)
if (r) { dev_dbg(dev, "Unable to add GPIO mapping table\n");
nfc_err(&client->dev, "No platform data\n");
return r; /* Get EN GPIO from resource provider */
} phy->gpiod_ena = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
} else if (ACPI_HANDLE(&client->dev)) { if (IS_ERR(phy->gpiod_ena)) {
r = st21nfca_hci_i2c_acpi_request_resources(client); nfc_err(dev, "Unable to get ENABLE GPIO\n");
if (r) { return PTR_ERR(phy->gpiod_ena);
nfc_err(&client->dev, "Cannot get ACPI data\n");
return r;
}
} else {
nfc_err(&client->dev, "st21nfca platform resources not available\n");
return -ENODEV;
} }
phy->se_status.is_ese_present = phy->se_status.is_ese_present =
......
...@@ -20,9 +20,8 @@ ...@@ -20,9 +20,8 @@
#include <linux/nfc.h> #include <linux/nfc.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
...@@ -127,7 +126,6 @@ ...@@ -127,7 +126,6 @@
#define TRF7970A_13MHZ_CLOCK_FREQUENCY 13560000 #define TRF7970A_13MHZ_CLOCK_FREQUENCY 13560000
#define TRF7970A_27MHZ_CLOCK_FREQUENCY 27120000 #define TRF7970A_27MHZ_CLOCK_FREQUENCY 27120000
#define TRF7970A_RX_SKB_ALLOC_SIZE 256 #define TRF7970A_RX_SKB_ALLOC_SIZE 256
#define TRF7970A_FIFO_SIZE 127 #define TRF7970A_FIFO_SIZE 127
...@@ -152,7 +150,6 @@ ...@@ -152,7 +150,6 @@
*/ */
#define TRF7970A_QUIRK_IRQ_STATUS_READ BIT(0) #define TRF7970A_QUIRK_IRQ_STATUS_READ BIT(0)
#define TRF7970A_QUIRK_EN2_MUST_STAY_LOW BIT(1) #define TRF7970A_QUIRK_EN2_MUST_STAY_LOW BIT(1)
#define TRF7970A_QUIRK_T5T_RMB_EXTRA_BYTE BIT(2)
/* Direct commands */ /* Direct commands */
#define TRF7970A_CMD_IDLE 0x00 #define TRF7970A_CMD_IDLE 0x00
...@@ -451,16 +448,14 @@ struct trf7970a { ...@@ -451,16 +448,14 @@ struct trf7970a {
u8 md_rf_tech; u8 md_rf_tech;
u8 tx_cmd; u8 tx_cmd;
bool issue_eof; bool issue_eof;
bool adjust_resp_len; struct gpio_desc *en_gpiod;
int en2_gpio; struct gpio_desc *en2_gpiod;
int en_gpio;
struct mutex lock; struct mutex lock;
unsigned int timeout; unsigned int timeout;
bool ignore_timeout; bool ignore_timeout;
struct delayed_work timeout_work; struct delayed_work timeout_work;
}; };
static int trf7970a_cmd(struct trf7970a *trf, u8 opcode) static int trf7970a_cmd(struct trf7970a *trf, u8 opcode)
{ {
u8 cmd = TRF7970A_CMD_BIT_CTRL | TRF7970A_CMD_BIT_OPCODE(opcode); u8 cmd = TRF7970A_CMD_BIT_CTRL | TRF7970A_CMD_BIT_OPCODE(opcode);
...@@ -490,7 +485,8 @@ static int trf7970a_read(struct trf7970a *trf, u8 reg, u8 *val) ...@@ -490,7 +485,8 @@ static int trf7970a_read(struct trf7970a *trf, u8 reg, u8 *val)
return ret; return ret;
} }
static int trf7970a_read_cont(struct trf7970a *trf, u8 reg, u8 *buf, size_t len) static int trf7970a_read_cont(struct trf7970a *trf, u8 reg, u8 *buf,
size_t len)
{ {
u8 addr = reg | TRF7970A_CMD_BIT_RW | TRF7970A_CMD_BIT_CONTINUOUS; u8 addr = reg | TRF7970A_CMD_BIT_RW | TRF7970A_CMD_BIT_CONTINUOUS;
struct spi_transfer t[2]; struct spi_transfer t[2];
...@@ -632,13 +628,6 @@ static void trf7970a_send_upstream(struct trf7970a *trf) ...@@ -632,13 +628,6 @@ static void trf7970a_send_upstream(struct trf7970a *trf)
trf->aborting = false; trf->aborting = false;
} }
if (trf->adjust_resp_len) {
if (trf->rx_skb)
skb_trim(trf->rx_skb, trf->rx_skb->len - 1);
trf->adjust_resp_len = false;
}
trf->cb(trf->ddev, trf->cb_arg, trf->rx_skb); trf->cb(trf->ddev, trf->cb_arg, trf->rx_skb);
trf->rx_skb = NULL; trf->rx_skb = NULL;
...@@ -657,7 +646,8 @@ static void trf7970a_send_err_upstream(struct trf7970a *trf, int errno) ...@@ -657,7 +646,8 @@ static void trf7970a_send_err_upstream(struct trf7970a *trf, int errno)
} }
static int trf7970a_transmit(struct trf7970a *trf, struct sk_buff *skb, static int trf7970a_transmit(struct trf7970a *trf, struct sk_buff *skb,
unsigned int len, u8 *prefix, unsigned int prefix_len) unsigned int len, u8 *prefix,
unsigned int prefix_len)
{ {
struct spi_transfer t[2]; struct spi_transfer t[2];
struct spi_message m; struct spi_message m;
...@@ -795,8 +785,7 @@ static void trf7970a_drain_fifo(struct trf7970a *trf, u8 status) ...@@ -795,8 +785,7 @@ static void trf7970a_drain_fifo(struct trf7970a *trf, u8 status)
/* If received Type 2 ACK/NACK, shift right 4 bits and pass up */ /* If received Type 2 ACK/NACK, shift right 4 bits and pass up */
if ((trf->framing == NFC_DIGITAL_FRAMING_NFCA_T2T) && (skb->len == 1) && if ((trf->framing == NFC_DIGITAL_FRAMING_NFCA_T2T) && (skb->len == 1) &&
(trf->special_fcn_reg1 == (trf->special_fcn_reg1 == TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX)) {
TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX)) {
skb->data[0] >>= 4; skb->data[0] >>= 4;
status = TRF7970A_IRQ_STATUS_SRX; status = TRF7970A_IRQ_STATUS_SRX;
} else { } else {
...@@ -905,8 +894,8 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id) ...@@ -905,8 +894,8 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id)
trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET); trf7970a_cmd(trf, TRF7970A_CMD_FIFO_RESET);
if (!trf->timeout) { if (!trf->timeout) {
trf->ignore_timeout = !cancel_delayed_work( trf->ignore_timeout =
&trf->timeout_work); !cancel_delayed_work(&trf->timeout_work);
trf->rx_skb = ERR_PTR(0); trf->rx_skb = ERR_PTR(0);
trf7970a_send_upstream(trf); trf7970a_send_upstream(trf);
break; break;
...@@ -1246,7 +1235,8 @@ static int trf7970a_is_rf_field(struct trf7970a *trf, bool *is_rf_field) ...@@ -1246,7 +1235,8 @@ static int trf7970a_is_rf_field(struct trf7970a *trf, bool *is_rf_field)
u8 rssi; u8 rssi;
ret = trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL, ret = trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL,
trf->chip_status_ctrl | TRF7970A_CHIP_STATUS_REC_ON); trf->chip_status_ctrl |
TRF7970A_CHIP_STATUS_REC_ON);
if (ret) if (ret)
return ret; return ret;
...@@ -1460,15 +1450,10 @@ static int trf7970a_per_cmd_config(struct trf7970a *trf, struct sk_buff *skb) ...@@ -1460,15 +1450,10 @@ static int trf7970a_per_cmd_config(struct trf7970a *trf, struct sk_buff *skb)
trf->iso_ctrl = iso_ctrl; trf->iso_ctrl = iso_ctrl;
} }
if (trf->framing == NFC_DIGITAL_FRAMING_ISO15693_T5T) { if ((trf->framing == NFC_DIGITAL_FRAMING_ISO15693_T5T) &&
if (trf7970a_is_iso15693_write_or_lock(req[1]) && trf7970a_is_iso15693_write_or_lock(req[1]) &&
(req[0] & ISO15693_REQ_FLAG_OPTION)) (req[0] & ISO15693_REQ_FLAG_OPTION))
trf->issue_eof = true; trf->issue_eof = true;
else if ((trf->quirks &
TRF7970A_QUIRK_T5T_RMB_EXTRA_BYTE) &&
(req[1] == ISO15693_CMD_READ_MULTIPLE_BLOCK))
trf->adjust_resp_len = true;
}
} }
return 0; return 0;
...@@ -1587,8 +1572,7 @@ static int trf7970a_tg_config_rf_tech(struct trf7970a *trf, int tech) ...@@ -1587,8 +1572,7 @@ static int trf7970a_tg_config_rf_tech(struct trf7970a *trf, int tech)
switch (tech) { switch (tech) {
case NFC_DIGITAL_RF_TECH_106A: case NFC_DIGITAL_RF_TECH_106A:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE | trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_CE | TRF7970A_ISO_CTRL_NFC_CE | TRF7970A_ISO_CTRL_NFC_CE_14443A;
TRF7970A_ISO_CTRL_NFC_CE_14443A;
trf->modulator_sys_clk_ctrl = trf->modulator_sys_clk_ctrl =
(trf->modulator_sys_clk_ctrl & 0xf8) | (trf->modulator_sys_clk_ctrl & 0xf8) |
TRF7970A_MODULATOR_DEPTH_OOK; TRF7970A_MODULATOR_DEPTH_OOK;
...@@ -1734,7 +1718,8 @@ static int trf7970a_tg_configure_hw(struct nfc_digital_dev *ddev, int type, ...@@ -1734,7 +1718,8 @@ static int trf7970a_tg_configure_hw(struct nfc_digital_dev *ddev, int type,
} }
static int _trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout, static int _trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
nfc_digital_cmd_complete_t cb, void *arg, bool mode_detect) nfc_digital_cmd_complete_t cb, void *arg,
bool mode_detect)
{ {
struct trf7970a *trf = nfc_digital_get_drvdata(ddev); struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
int ret; int ret;
...@@ -1819,7 +1804,8 @@ static int trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout, ...@@ -1819,7 +1804,8 @@ static int trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
} }
static int trf7970a_tg_listen_md(struct nfc_digital_dev *ddev, static int trf7970a_tg_listen_md(struct nfc_digital_dev *ddev,
u16 timeout, nfc_digital_cmd_complete_t cb, void *arg) u16 timeout, nfc_digital_cmd_complete_t cb,
void *arg)
{ {
struct trf7970a *trf = nfc_digital_get_drvdata(ddev); struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
int ret; int ret;
...@@ -1908,14 +1894,13 @@ static int trf7970a_power_up(struct trf7970a *trf) ...@@ -1908,14 +1894,13 @@ static int trf7970a_power_up(struct trf7970a *trf)
usleep_range(5000, 6000); usleep_range(5000, 6000);
if (!(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW)) { if (trf->en2_gpiod &&
if (gpio_is_valid(trf->en2_gpio)) { !(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW)) {
gpio_set_value(trf->en2_gpio, 1); gpiod_set_value_cansleep(trf->en2_gpiod, 1);
usleep_range(1000, 2000); usleep_range(1000, 2000);
} }
}
gpio_set_value(trf->en_gpio, 1); gpiod_set_value_cansleep(trf->en_gpiod, 1);
usleep_range(20000, 21000); usleep_range(20000, 21000);
...@@ -1939,9 +1924,10 @@ static int trf7970a_power_down(struct trf7970a *trf) ...@@ -1939,9 +1924,10 @@ static int trf7970a_power_down(struct trf7970a *trf)
return -EBUSY; return -EBUSY;
} }
gpio_set_value(trf->en_gpio, 0); gpiod_set_value_cansleep(trf->en_gpiod, 0);
if (gpio_is_valid(trf->en2_gpio))
gpio_set_value(trf->en2_gpio, 0); if (trf->en2_gpiod && !(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW))
gpiod_set_value_cansleep(trf->en2_gpiod, 0);
ret = regulator_disable(trf->regulator); ret = regulator_disable(trf->regulator);
if (ret) if (ret)
...@@ -2003,12 +1989,6 @@ static int trf7970a_get_autosuspend_delay(struct device_node *np) ...@@ -2003,12 +1989,6 @@ static int trf7970a_get_autosuspend_delay(struct device_node *np)
return autosuspend_delay; return autosuspend_delay;
} }
static int trf7970a_get_vin_voltage_override(struct device_node *np,
u32 *vin_uvolts)
{
return of_property_read_u32(np, "vin-voltage-override", vin_uvolts);
}
static int trf7970a_probe(struct spi_device *spi) static int trf7970a_probe(struct spi_device *spi)
{ {
struct device_node *np = spi->dev.of_node; struct device_node *np = spi->dev.of_node;
...@@ -2038,52 +2018,47 @@ static int trf7970a_probe(struct spi_device *spi) ...@@ -2038,52 +2018,47 @@ static int trf7970a_probe(struct spi_device *spi)
return ret; return ret;
} }
if (of_property_read_bool(np, "t5t-rmb-extra-byte-quirk"))
trf->quirks |= TRF7970A_QUIRK_T5T_RMB_EXTRA_BYTE;
if (of_property_read_bool(np, "irq-status-read-quirk")) if (of_property_read_bool(np, "irq-status-read-quirk"))
trf->quirks |= TRF7970A_QUIRK_IRQ_STATUS_READ; trf->quirks |= TRF7970A_QUIRK_IRQ_STATUS_READ;
/* There are two enable pins - both must be present */ /* There are two enable pins - only EN must be present in the DT */
trf->en_gpio = of_get_named_gpio(np, "ti,enable-gpios", 0); trf->en_gpiod = devm_gpiod_get_index(trf->dev, "ti,enable", 0,
if (!gpio_is_valid(trf->en_gpio)) { GPIOD_OUT_LOW);
if (IS_ERR(trf->en_gpiod)) {
dev_err(trf->dev, "No EN GPIO property\n"); dev_err(trf->dev, "No EN GPIO property\n");
return trf->en_gpio; return PTR_ERR(trf->en_gpiod);
} }
ret = devm_gpio_request_one(trf->dev, trf->en_gpio, trf->en2_gpiod = devm_gpiod_get_index_optional(trf->dev, "ti,enable", 1,
GPIOF_DIR_OUT | GPIOF_INIT_LOW, "trf7970a EN"); GPIOD_OUT_LOW);
if (ret) { if (!trf->en2_gpiod) {
dev_err(trf->dev, "Can't request EN GPIO: %d\n", ret);
return ret;
}
trf->en2_gpio = of_get_named_gpio(np, "ti,enable-gpios", 1);
if (!gpio_is_valid(trf->en2_gpio)) {
dev_info(trf->dev, "No EN2 GPIO property\n"); dev_info(trf->dev, "No EN2 GPIO property\n");
} else { } else if (IS_ERR(trf->en2_gpiod)) {
ret = devm_gpio_request_one(trf->dev, trf->en2_gpio, dev_err(trf->dev, "Error getting EN2 GPIO property: %ld\n",
GPIOF_DIR_OUT | GPIOF_INIT_LOW, "trf7970a EN2"); PTR_ERR(trf->en2_gpiod));
if (ret) { return PTR_ERR(trf->en2_gpiod);
dev_err(trf->dev, "Can't request EN2 GPIO: %d\n", ret); } else if (of_property_read_bool(np, "en2-rf-quirk")) {
return ret; trf->quirks |= TRF7970A_QUIRK_EN2_MUST_STAY_LOW;
}
} }
of_property_read_u32(np, "clock-frequency", &clk_freq); of_property_read_u32(np, "clock-frequency", &clk_freq);
if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) || if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) &&
(clk_freq != TRF7970A_13MHZ_CLOCK_FREQUENCY)) { (clk_freq != TRF7970A_13MHZ_CLOCK_FREQUENCY)) {
dev_err(trf->dev, dev_err(trf->dev,
"clock-frequency (%u Hz) unsupported\n", "clock-frequency (%u Hz) unsupported\n", clk_freq);
clk_freq);
return -EINVAL; return -EINVAL;
} }
if (of_property_read_bool(np, "en2-rf-quirk")) if (clk_freq == TRF7970A_27MHZ_CLOCK_FREQUENCY) {
trf->quirks |= TRF7970A_QUIRK_EN2_MUST_STAY_LOW; trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_27MHZ;
dev_dbg(trf->dev, "trf7970a configured for 27MHz crystal\n");
} else {
trf->modulator_sys_clk_ctrl = 0;
}
ret = devm_request_threaded_irq(trf->dev, spi->irq, NULL, ret = devm_request_threaded_irq(trf->dev, spi->irq, NULL,
trf7970a_irq, IRQF_TRIGGER_RISING | IRQF_ONESHOT, trf7970a_irq,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"trf7970a", trf); "trf7970a", trf);
if (ret) { if (ret) {
dev_err(trf->dev, "Can't request IRQ#%d: %d\n", spi->irq, ret); dev_err(trf->dev, "Can't request IRQ#%d: %d\n", spi->irq, ret);
...@@ -2106,10 +2081,7 @@ static int trf7970a_probe(struct spi_device *spi) ...@@ -2106,10 +2081,7 @@ static int trf7970a_probe(struct spi_device *spi)
goto err_destroy_lock; goto err_destroy_lock;
} }
ret = trf7970a_get_vin_voltage_override(np, &uvolts);
if (ret)
uvolts = regulator_get_voltage(trf->regulator); uvolts = regulator_get_voltage(trf->regulator);
if (uvolts > 4000000) if (uvolts > 4000000)
trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3; trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3;
...@@ -2134,7 +2106,8 @@ static int trf7970a_probe(struct spi_device *spi) ...@@ -2134,7 +2106,8 @@ static int trf7970a_probe(struct spi_device *spi)
trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops, trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops,
TRF7970A_SUPPORTED_PROTOCOLS, TRF7970A_SUPPORTED_PROTOCOLS,
NFC_DIGITAL_DRV_CAPS_IN_CRC | NFC_DIGITAL_DRV_CAPS_IN_CRC |
NFC_DIGITAL_DRV_CAPS_TG_CRC, 0, 0); NFC_DIGITAL_DRV_CAPS_TG_CRC, 0,
0);
if (!trf->ddev) { if (!trf->ddev) {
dev_err(trf->dev, "Can't allocate NFC digital device\n"); dev_err(trf->dev, "Can't allocate NFC digital device\n");
ret = -ENOMEM; ret = -ENOMEM;
...@@ -2270,15 +2243,17 @@ static const struct dev_pm_ops trf7970a_pm_ops = { ...@@ -2270,15 +2243,17 @@ static const struct dev_pm_ops trf7970a_pm_ops = {
}; };
static const struct of_device_id trf7970a_of_match[] = { static const struct of_device_id trf7970a_of_match[] = {
{ .compatible = "ti,trf7970a", }, {.compatible = "ti,trf7970a",},
{ /* sentinel */ }, {},
}; };
MODULE_DEVICE_TABLE(of, trf7970a_of_match); MODULE_DEVICE_TABLE(of, trf7970a_of_match);
static const struct spi_device_id trf7970a_id_table[] = { static const struct spi_device_id trf7970a_id_table[] = {
{ "trf7970a", 0 }, {"trf7970a", 0},
{ } {}
}; };
MODULE_DEVICE_TABLE(spi, trf7970a_id_table); MODULE_DEVICE_TABLE(spi, trf7970a_id_table);
static struct spi_driver trf7970a_spi_driver = { static struct spi_driver trf7970a_spi_driver = {
......
...@@ -23,7 +23,7 @@ struct nfcmrvl_platform_data { ...@@ -23,7 +23,7 @@ struct nfcmrvl_platform_data {
*/ */
/* GPIO that is wired to RESET_N signal */ /* GPIO that is wired to RESET_N signal */
unsigned int reset_n_io; int reset_n_io;
/* Tell if transport is muxed in HCI one */ /* Tell if transport is muxed in HCI one */
unsigned int hci_muxed; unsigned int hci_muxed;
......
/*
* Driver include for ST NCI NFC chip family.
*
* Copyright (C) 2014-2015 STMicroelectronics SAS. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ST_NCI_H_
#define _ST_NCI_H_
#define ST_NCI_DRIVER_NAME "st_nci"
struct st_nci_nfc_platform_data {
unsigned int gpio_reset;
unsigned int irq_polarity;
bool is_ese_present;
bool is_uicc_present;
};
#endif /* _ST_NCI_H_ */
...@@ -982,6 +982,8 @@ static void nfc_release(struct device *d) ...@@ -982,6 +982,8 @@ static void nfc_release(struct device *d)
kfree(se); kfree(se);
} }
ida_simple_remove(&nfc_index_ida, dev->idx);
kfree(dev); kfree(dev);
} }
...@@ -1056,6 +1058,7 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, ...@@ -1056,6 +1058,7 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
int tx_headroom, int tx_tailroom) int tx_headroom, int tx_tailroom)
{ {
struct nfc_dev *dev; struct nfc_dev *dev;
int rc;
if (!ops->start_poll || !ops->stop_poll || !ops->activate_target || if (!ops->start_poll || !ops->stop_poll || !ops->activate_target ||
!ops->deactivate_target || !ops->im_transceive) !ops->deactivate_target || !ops->im_transceive)
...@@ -1068,6 +1071,15 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, ...@@ -1068,6 +1071,15 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
if (!dev) if (!dev)
return NULL; return NULL;
rc = ida_simple_get(&nfc_index_ida, 0, 0, GFP_KERNEL);
if (rc < 0)
goto err_free_dev;
dev->idx = rc;
dev->dev.class = &nfc_class;
dev_set_name(&dev->dev, "nfc%d", dev->idx);
device_initialize(&dev->dev);
dev->ops = ops; dev->ops = ops;
dev->supported_protocols = supported_protocols; dev->supported_protocols = supported_protocols;
dev->tx_headroom = tx_headroom; dev->tx_headroom = tx_headroom;
...@@ -1090,6 +1102,11 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, ...@@ -1090,6 +1102,11 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
} }
return dev; return dev;
err_free_dev:
kfree(dev);
return ERR_PTR(rc);
} }
EXPORT_SYMBOL(nfc_allocate_device); EXPORT_SYMBOL(nfc_allocate_device);
...@@ -1104,14 +1121,6 @@ int nfc_register_device(struct nfc_dev *dev) ...@@ -1104,14 +1121,6 @@ int nfc_register_device(struct nfc_dev *dev)
pr_debug("dev_name=%s\n", dev_name(&dev->dev)); pr_debug("dev_name=%s\n", dev_name(&dev->dev));
dev->idx = ida_simple_get(&nfc_index_ida, 0, 0, GFP_KERNEL);
if (dev->idx < 0)
return dev->idx;
dev->dev.class = &nfc_class;
dev_set_name(&dev->dev, "nfc%d", dev->idx);
device_initialize(&dev->dev);
mutex_lock(&nfc_devlist_mutex); mutex_lock(&nfc_devlist_mutex);
nfc_devlist_generation++; nfc_devlist_generation++;
rc = device_add(&dev->dev); rc = device_add(&dev->dev);
...@@ -1149,12 +1158,10 @@ EXPORT_SYMBOL(nfc_register_device); ...@@ -1149,12 +1158,10 @@ EXPORT_SYMBOL(nfc_register_device);
*/ */
void nfc_unregister_device(struct nfc_dev *dev) void nfc_unregister_device(struct nfc_dev *dev)
{ {
int rc, id; int rc;
pr_debug("dev_name=%s\n", dev_name(&dev->dev)); pr_debug("dev_name=%s\n", dev_name(&dev->dev));
id = dev->idx;
if (dev->rfkill) { if (dev->rfkill) {
rfkill_unregister(dev->rfkill); rfkill_unregister(dev->rfkill);
rfkill_destroy(dev->rfkill); rfkill_destroy(dev->rfkill);
...@@ -1179,8 +1186,6 @@ void nfc_unregister_device(struct nfc_dev *dev) ...@@ -1179,8 +1186,6 @@ void nfc_unregister_device(struct nfc_dev *dev)
nfc_devlist_generation++; nfc_devlist_generation++;
device_del(&dev->dev); device_del(&dev->dev);
mutex_unlock(&nfc_devlist_mutex); mutex_unlock(&nfc_devlist_mutex);
ida_simple_remove(&nfc_index_ida, id);
} }
EXPORT_SYMBOL(nfc_unregister_device); EXPORT_SYMBOL(nfc_unregister_device);
......
...@@ -240,7 +240,7 @@ int digital_send_cmd(struct nfc_digital_dev *ddev, u8 cmd_type, ...@@ -240,7 +240,7 @@ int digital_send_cmd(struct nfc_digital_dev *ddev, u8 cmd_type,
{ {
struct digital_cmd *cmd; struct digital_cmd *cmd;
cmd = kzalloc(sizeof(struct digital_cmd), GFP_KERNEL); cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (!cmd) if (!cmd)
return -ENOMEM; return -ENOMEM;
...@@ -287,7 +287,7 @@ static int digital_tg_listen_mdaa(struct nfc_digital_dev *ddev, u8 rf_tech) ...@@ -287,7 +287,7 @@ static int digital_tg_listen_mdaa(struct nfc_digital_dev *ddev, u8 rf_tech)
{ {
struct digital_tg_mdaa_params *params; struct digital_tg_mdaa_params *params;
params = kzalloc(sizeof(struct digital_tg_mdaa_params), GFP_KERNEL); params = kzalloc(sizeof(*params), GFP_KERNEL);
if (!params) if (!params)
return -ENOMEM; return -ENOMEM;
...@@ -706,11 +706,9 @@ static int digital_in_send(struct nfc_dev *nfc_dev, struct nfc_target *target, ...@@ -706,11 +706,9 @@ static int digital_in_send(struct nfc_dev *nfc_dev, struct nfc_target *target,
struct digital_data_exch *data_exch; struct digital_data_exch *data_exch;
int rc; int rc;
data_exch = kzalloc(sizeof(struct digital_data_exch), GFP_KERNEL); data_exch = kzalloc(sizeof(*data_exch), GFP_KERNEL);
if (!data_exch) { if (!data_exch)
pr_err("Failed to allocate data_exch struct\n");
return -ENOMEM; return -ENOMEM;
}
data_exch->cb = cb; data_exch->cb = cb;
data_exch->cb_context = cb_context; data_exch->cb_context = cb_context;
...@@ -764,7 +762,7 @@ struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops, ...@@ -764,7 +762,7 @@ struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops,
!ops->switch_rf || (ops->tg_listen_md && !ops->tg_get_rf_tech)) !ops->switch_rf || (ops->tg_listen_md && !ops->tg_get_rf_tech))
return NULL; return NULL;
ddev = kzalloc(sizeof(struct nfc_digital_dev), GFP_KERNEL); ddev = kzalloc(sizeof(*ddev), GFP_KERNEL);
if (!ddev) if (!ddev)
return NULL; return NULL;
......
...@@ -151,7 +151,7 @@ static const u8 digital_payload_bits_map[4] = { ...@@ -151,7 +151,7 @@ static const u8 digital_payload_bits_map[4] = {
* 0 <= wt <= 14 (given by the target by the TO field of ATR_RES response) * 0 <= wt <= 14 (given by the target by the TO field of ATR_RES response)
*/ */
#define DIGITAL_NFC_DEP_IN_MAX_WT 14 #define DIGITAL_NFC_DEP_IN_MAX_WT 14
#define DIGITAL_NFC_DEP_TG_MAX_WT 8 #define DIGITAL_NFC_DEP_TG_MAX_WT 14
static const u16 digital_rwt_map[DIGITAL_NFC_DEP_IN_MAX_WT + 1] = { static const u16 digital_rwt_map[DIGITAL_NFC_DEP_IN_MAX_WT + 1] = {
100, 101, 101, 102, 105, 100, 101, 101, 102, 105,
110, 119, 139, 177, 255, 110, 119, 139, 177, 255,
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#define DIGITAL_SDD_RES_CT 0x88 #define DIGITAL_SDD_RES_CT 0x88
#define DIGITAL_SDD_RES_LEN 5 #define DIGITAL_SDD_RES_LEN 5
#define DIGITAL_SEL_RES_LEN 1
#define DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res) (!((sel_res) & 0x04)) #define DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res) (!((sel_res) & 0x04))
#define DIGITAL_SEL_RES_IS_T2T(sel_res) (!((sel_res) & 0x60)) #define DIGITAL_SEL_RES_IS_T2T(sel_res) (!((sel_res) & 0x60))
...@@ -299,7 +300,7 @@ static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg, ...@@ -299,7 +300,7 @@ static void digital_in_recv_sel_res(struct nfc_digital_dev *ddev, void *arg,
} }
} }
if (!resp->len) { if (resp->len != DIGITAL_SEL_RES_LEN) {
rc = -EIO; rc = -EIO;
goto exit; goto exit;
} }
......
...@@ -77,7 +77,8 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) ...@@ -77,7 +77,8 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
struct sockaddr_nfc_llcp llcp_addr; struct sockaddr_nfc_llcp llcp_addr;
int len, ret = 0; int len, ret = 0;
if (!addr || addr->sa_family != AF_NFC) if (!addr || alen < offsetofend(struct sockaddr, sa_family) ||
addr->sa_family != AF_NFC)
return -EINVAL; return -EINVAL;
pr_debug("sk %p addr %p family %d\n", sk, addr, addr->sa_family); pr_debug("sk %p addr %p family %d\n", sk, addr, addr->sa_family);
...@@ -151,7 +152,8 @@ static int llcp_raw_sock_bind(struct socket *sock, struct sockaddr *addr, ...@@ -151,7 +152,8 @@ static int llcp_raw_sock_bind(struct socket *sock, struct sockaddr *addr,
struct sockaddr_nfc_llcp llcp_addr; struct sockaddr_nfc_llcp llcp_addr;
int len, ret = 0; int len, ret = 0;
if (!addr || addr->sa_family != AF_NFC) if (!addr || alen < offsetofend(struct sockaddr, sa_family) ||
addr->sa_family != AF_NFC)
return -EINVAL; return -EINVAL;
pr_debug("sk %p addr %p family %d\n", sk, addr, addr->sa_family); pr_debug("sk %p addr %p family %d\n", sk, addr, addr->sa_family);
...@@ -662,8 +664,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, ...@@ -662,8 +664,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
pr_debug("sock %p sk %p flags 0x%x\n", sock, sk, flags); pr_debug("sock %p sk %p flags 0x%x\n", sock, sk, flags);
if (!addr || len < sizeof(struct sockaddr_nfc) || if (!addr || len < sizeof(*addr) || addr->sa_family != AF_NFC)
addr->sa_family != AF_NFC)
return -EINVAL; return -EINVAL;
if (addr->service_name_len == 0 && addr->dsap == 0) if (addr->service_name_len == 0 && addr->dsap == 0)
......
...@@ -73,13 +73,12 @@ int nci_get_conn_info_by_dest_type_params(struct nci_dev *ndev, u8 dest_type, ...@@ -73,13 +73,12 @@ int nci_get_conn_info_by_dest_type_params(struct nci_dev *ndev, u8 dest_type,
if (conn_info->dest_type == dest_type) { if (conn_info->dest_type == dest_type) {
if (!params) if (!params)
return conn_info->conn_id; return conn_info->conn_id;
if (conn_info) {
if (params->id == conn_info->dest_params->id && if (params->id == conn_info->dest_params->id &&
params->protocol == conn_info->dest_params->protocol) params->protocol == conn_info->dest_params->protocol)
return conn_info->conn_id; return conn_info->conn_id;
} }
} }
}
return -EINVAL; return -EINVAL;
} }
...@@ -1173,8 +1172,7 @@ struct nci_dev *nci_allocate_device(struct nci_ops *ops, ...@@ -1173,8 +1172,7 @@ struct nci_dev *nci_allocate_device(struct nci_ops *ops,
return ndev; return ndev;
free_nfc: free_nfc:
kfree(ndev->nfc_dev); nfc_free_device(ndev->nfc_dev);
free_nci: free_nci:
kfree(ndev); kfree(ndev);
return NULL; return NULL;
......
...@@ -907,7 +907,9 @@ static int nfc_genl_activate_target(struct sk_buff *skb, struct genl_info *info) ...@@ -907,7 +907,9 @@ static int nfc_genl_activate_target(struct sk_buff *skb, struct genl_info *info)
u32 device_idx, target_idx, protocol; u32 device_idx, target_idx, protocol;
int rc; int rc;
if (!info->attrs[NFC_ATTR_DEVICE_INDEX]) if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
!info->attrs[NFC_ATTR_TARGET_INDEX] ||
!info->attrs[NFC_ATTR_PROTOCOLS])
return -EINVAL; return -EINVAL;
device_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); device_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment