mirror of
https://github.com/torvalds/linux.git
synced 2026-05-05 23:05:25 -04:00
This was done entirely with mindless brute force, using
git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'
to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.
Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.
For the same reason the 'flex' versions will be done as a separate
conversion.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
204 lines
4.4 KiB
C
204 lines
4.4 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Broadcom B43 wireless driver
|
|
*
|
|
* SDIO over Sonics Silicon Backplane bus glue for b43.
|
|
*
|
|
* Copyright (C) 2009 Albert Herranz
|
|
* Copyright (C) 2009 Michael Buesch <m@bues.ch>
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/mmc/card.h>
|
|
#include <linux/mmc/sdio_func.h>
|
|
#include <linux/mmc/sdio_ids.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/ssb/ssb.h>
|
|
|
|
#include "sdio.h"
|
|
#include "b43.h"
|
|
|
|
|
|
#define HNBU_CHIPID 0x01 /* vendor & device id */
|
|
|
|
#define B43_SDIO_BLOCK_SIZE 64 /* rx fifo max size in bytes */
|
|
|
|
|
|
static const struct b43_sdio_quirk {
|
|
u16 vendor;
|
|
u16 device;
|
|
unsigned int quirks;
|
|
} b43_sdio_quirks[] = {
|
|
{ 0x14E4, 0x4318, SSB_QUIRK_SDIO_READ_AFTER_WRITE32, },
|
|
{ },
|
|
};
|
|
|
|
|
|
static unsigned int b43_sdio_get_quirks(u16 vendor, u16 device)
|
|
{
|
|
const struct b43_sdio_quirk *q;
|
|
|
|
for (q = b43_sdio_quirks; q->quirks; q++) {
|
|
if (vendor == q->vendor && device == q->device)
|
|
return q->quirks;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void b43_sdio_interrupt_dispatcher(struct sdio_func *func)
|
|
{
|
|
struct b43_sdio *sdio = sdio_get_drvdata(func);
|
|
struct b43_wldev *dev = sdio->irq_handler_opaque;
|
|
|
|
if (unlikely(b43_status(dev) < B43_STAT_STARTED))
|
|
return;
|
|
|
|
sdio_release_host(func);
|
|
sdio->irq_handler(dev);
|
|
sdio_claim_host(func);
|
|
}
|
|
|
|
int b43_sdio_request_irq(struct b43_wldev *dev,
|
|
void (*handler)(struct b43_wldev *dev))
|
|
{
|
|
struct ssb_bus *bus = dev->dev->sdev->bus;
|
|
struct sdio_func *func = bus->host_sdio;
|
|
struct b43_sdio *sdio = sdio_get_drvdata(func);
|
|
int err;
|
|
|
|
sdio->irq_handler_opaque = dev;
|
|
sdio->irq_handler = handler;
|
|
sdio_claim_host(func);
|
|
err = sdio_claim_irq(func, b43_sdio_interrupt_dispatcher);
|
|
sdio_release_host(func);
|
|
|
|
return err;
|
|
}
|
|
|
|
void b43_sdio_free_irq(struct b43_wldev *dev)
|
|
{
|
|
struct ssb_bus *bus = dev->dev->sdev->bus;
|
|
struct sdio_func *func = bus->host_sdio;
|
|
struct b43_sdio *sdio = sdio_get_drvdata(func);
|
|
|
|
sdio_claim_host(func);
|
|
sdio_release_irq(func);
|
|
sdio_release_host(func);
|
|
sdio->irq_handler_opaque = NULL;
|
|
sdio->irq_handler = NULL;
|
|
}
|
|
|
|
static int b43_sdio_probe(struct sdio_func *func,
|
|
const struct sdio_device_id *id)
|
|
{
|
|
struct b43_sdio *sdio;
|
|
struct sdio_func_tuple *tuple;
|
|
u16 vendor = 0, device = 0;
|
|
int error;
|
|
|
|
/* Look for the card chip identifier. */
|
|
tuple = func->tuples;
|
|
while (tuple) {
|
|
switch (tuple->code) {
|
|
case 0x80:
|
|
switch (tuple->data[0]) {
|
|
case HNBU_CHIPID:
|
|
if (tuple->size != 5)
|
|
break;
|
|
vendor = tuple->data[1] | (tuple->data[2]<<8);
|
|
device = tuple->data[3] | (tuple->data[4]<<8);
|
|
dev_info(&func->dev, "Chip ID %04x:%04x\n",
|
|
vendor, device);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
tuple = tuple->next;
|
|
}
|
|
if (!vendor || !device) {
|
|
error = -ENODEV;
|
|
goto out;
|
|
}
|
|
|
|
sdio_claim_host(func);
|
|
error = sdio_set_block_size(func, B43_SDIO_BLOCK_SIZE);
|
|
if (error) {
|
|
dev_err(&func->dev, "failed to set block size to %u bytes,"
|
|
" error %d\n", B43_SDIO_BLOCK_SIZE, error);
|
|
goto err_release_host;
|
|
}
|
|
error = sdio_enable_func(func);
|
|
if (error) {
|
|
dev_err(&func->dev, "failed to enable func, error %d\n", error);
|
|
goto err_release_host;
|
|
}
|
|
sdio_release_host(func);
|
|
|
|
sdio = kzalloc_obj(*sdio);
|
|
if (!sdio) {
|
|
error = -ENOMEM;
|
|
dev_err(&func->dev, "failed to allocate ssb bus\n");
|
|
goto err_disable_func;
|
|
}
|
|
error = ssb_bus_sdiobus_register(&sdio->ssb, func,
|
|
b43_sdio_get_quirks(vendor, device));
|
|
if (error) {
|
|
dev_err(&func->dev, "failed to register ssb sdio bus,"
|
|
" error %d\n", error);
|
|
goto err_free_ssb;
|
|
}
|
|
sdio_set_drvdata(func, sdio);
|
|
|
|
return 0;
|
|
|
|
err_free_ssb:
|
|
kfree(sdio);
|
|
err_disable_func:
|
|
sdio_claim_host(func);
|
|
sdio_disable_func(func);
|
|
err_release_host:
|
|
sdio_release_host(func);
|
|
out:
|
|
return error;
|
|
}
|
|
|
|
static void b43_sdio_remove(struct sdio_func *func)
|
|
{
|
|
struct b43_sdio *sdio = sdio_get_drvdata(func);
|
|
|
|
ssb_bus_unregister(&sdio->ssb);
|
|
sdio_claim_host(func);
|
|
sdio_disable_func(func);
|
|
sdio_release_host(func);
|
|
kfree(sdio);
|
|
sdio_set_drvdata(func, NULL);
|
|
}
|
|
|
|
static const struct sdio_device_id b43_sdio_ids[] = {
|
|
{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_NINTENDO_WII) },
|
|
{ SDIO_DEVICE(SDIO_VENDOR_ID_CGUYS, SDIO_DEVICE_ID_CGUYS_EW_CG1102GC) },
|
|
{ },
|
|
};
|
|
|
|
static struct sdio_driver b43_sdio_driver = {
|
|
.name = "b43-sdio",
|
|
.id_table = b43_sdio_ids,
|
|
.probe = b43_sdio_probe,
|
|
.remove = b43_sdio_remove,
|
|
};
|
|
|
|
int b43_sdio_init(void)
|
|
{
|
|
return sdio_register_driver(&b43_sdio_driver);
|
|
}
|
|
|
|
void b43_sdio_exit(void)
|
|
{
|
|
sdio_unregister_driver(&b43_sdio_driver);
|
|
}
|