ANDROID: serdev: restrict claim of platform devices

Make the fallback path for claiming platform devices trigger only if a
new module parameter is specified:

  serdev_ttyport.pdev_tty_port=ttyS2

Bug: 146517987
Change-Id: Ibf331ad6e6d8712a405921530f217f7122428b13
Signed-off-by: Alistair Delva <adelva@google.com>
This commit is contained in:
Alistair Delva
2020-03-04 12:03:23 -08:00
parent 8af3a47b0a
commit 1f441a86a6
3 changed files with 47 additions and 8 deletions

View File

@@ -623,16 +623,18 @@ static int platform_serdev_register_devices(struct serdev_controller *ctrl)
return err;
}
/**
* serdev_controller_add() - Add an serdev controller
* serdev_controller_add_platform() - Add an serdev controller
* @ctrl: controller to be registered.
* @platform: whether to permit fallthrough to platform device probe
*
* Register a controller previously allocated via serdev_controller_alloc() with
* the serdev core.
* the serdev core. Optionally permit probing via a platform device fallback.
*/
int serdev_controller_add(struct serdev_controller *ctrl)
int serdev_controller_add_platform(struct serdev_controller *ctrl, bool platform)
{
int ret_of, ret_acpi, ret_platform, ret;
int ret, ret_of, ret_acpi, ret_platform = -ENODEV;
/* Can't register until after driver model init */
if (WARN_ON(!is_registered))
@@ -646,6 +648,7 @@ int serdev_controller_add(struct serdev_controller *ctrl)
ret_of = of_serdev_register_devices(ctrl);
ret_acpi = acpi_serdev_register_devices(ctrl);
if (platform)
ret_platform = platform_serdev_register_devices(ctrl);
if (ret_of && ret_acpi && ret_platform) {
dev_dbg(&ctrl->dev, "no devices registered: of:%d acpi:%d "
@@ -664,7 +667,7 @@ int serdev_controller_add(struct serdev_controller *ctrl)
device_del(&ctrl->dev);
return ret;
};
EXPORT_SYMBOL_GPL(serdev_controller_add);
EXPORT_SYMBOL_GPL(serdev_controller_add_platform);
/* Remove a device associated with a controller */
static int serdev_remove_device(struct device *dev, void *data)

View File

@@ -7,9 +7,15 @@
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/poll.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#define SERPORT_ACTIVE 1
static char *pdev_tty_port;
module_param(pdev_tty_port, charp, 0644);
MODULE_PARM_DESC(pdev_tty_port, "platform device tty port to claim");
struct serport {
struct tty_port *port;
struct tty_struct *tty;
@@ -267,6 +273,7 @@ struct device *serdev_tty_port_register(struct tty_port *port,
{
struct serdev_controller *ctrl;
struct serport *serport;
bool platform = false;
int ret;
if (!port || !drv || !parent)
@@ -291,7 +298,24 @@ struct device *serdev_tty_port_register(struct tty_port *port,
port->client_ops = &client_ops;
port->client_data = ctrl;
ret = serdev_controller_add(ctrl);
/* There is not always a way to bind specific platform devices because
* they may be defined on platforms without DT or ACPI. When dealing
* with a platform devices, do not allow direct binding unless it is
* whitelisted by module parameter. If a platform device is otherwise
* described by DT or ACPI it will still be bound and this check will
* be ignored.
*/
if (parent->bus == &platform_bus_type) {
char tty_port_name[7];
sprintf(tty_port_name, "%s%d", drv->name, idx);
if (pdev_tty_port &&
!strcmp(pdev_tty_port, tty_port_name)) {
platform = true;
}
}
ret = serdev_controller_add_platform(ctrl, platform);
if (ret)
goto err_reset_data;

View File

@@ -173,9 +173,21 @@ int serdev_device_add(struct serdev_device *);
void serdev_device_remove(struct serdev_device *);
struct serdev_controller *serdev_controller_alloc(struct device *, size_t);
int serdev_controller_add(struct serdev_controller *);
int serdev_controller_add_platform(struct serdev_controller *, bool);
void serdev_controller_remove(struct serdev_controller *);
/**
* serdev_controller_add() - Add an serdev controller
* @ctrl: controller to be registered.
*
* Register a controller previously allocated via serdev_controller_alloc() with
* the serdev core.
*/
static inline int serdev_controller_add(struct serdev_controller *ctrl)
{
return serdev_controller_add_platform(ctrl, false);
}
static inline void serdev_controller_write_wakeup(struct serdev_controller *ctrl)
{
struct serdev_device *serdev = ctrl->serdev;